Я возился с этим целый час, так и не понял, почему это не сработает. У меня есть проект, который выводит 3 xlsx и docx файлы во временную папку (/ temp). Я хочу заархивировать их для скачивания.
Проблема в том, что каждый раз, когда я выполняю команду 7z, она вместо этого архивирует всю папку проекта (../temp), даже не только временную папку. Я не могу понять, почему. Если я эхо $command
и запустить его в cmd из рабочего каталога PHP (что в любом случае не должно иметь значения, поскольку я использую абсолютные пути для всего), работает просто отлично. Это также не работает, если я использую относительные пути.
Переменные имени файла $HSModuleFileName
и т. д. генерируются в другом месте, заканчиваясь либо «.docx», либо «.xlsx»
$project_dir = str_replace('\\', '/', preg_replace('/\\|\/$/', '', dirname(dirname(__DIR__)))) . '/';
$FileName = 'output_' . substr($ImportGUID, -8) . '.zip';$command = '"C:/Program Files/7-Zip/7z.exe" a -tzip "' . $project_dir . 'temp/' . $FileName . '""' . $project_dir . 'temp/' . $HSModuleFileName . '" "' . $project_dir . 'temp/' . $SummaryFileName . '" "' . $project_dir . 'temp/' . $NoInvoiceFileName . '"';exec($command);
Эхо $ command:
"C:/Program Files/7-Zip/7z.exe" a -tzip "D:/Projects/JFC/temp/output_38416fc5.zip" "D:/Projects/JFC/temp/HS_Module_38416fc5.xlsx" "D:/Projects/JFC/temp/Summary_38416fc5.xlsx" "D:/Projects/JFC/temp/NoInvoice_38416fc5.docx"
Так что в результате output_38416fc5.zip
файл фактически содержит всю папку «D: / Projects / JFC»
Нашел это! Спасибо @ n0rd за указание в правильном направлении. Используя sysinternals Process Monitor, я увидел, что в событии Start Start для 7z параметр командной строки был
"C:/Program Files/7-Zip/7z.exe" a -tzip "D:/Projects/JFC/temp/output_de75eb91.zip"
без списка файлов.
Затем я внезапно понял, что разделил команду с помощью новой строки в коде PHP, непосредственно перед списком файлов, что означало, что она также была обработана exec как новая строка.
Других решений пока нет …