ZipArchive::addFile() создает zip-файлы с древовидной структурой в Windows, но сглаженные в Linux

#php #ziparchive

Вопрос:

Я использовал библиотеку ZipArchive PHP для создания zip-файла, чтобы легко переносить изображения для какой-либо службы синхронизации интернет-магазина с рабочего стола на веб-сервер интернет-магазина. Сценарий, который я использовал для создания почтового индекса, приведен ниже:

 function compress(string $path)
{
    $zip = new ZipArchive();
    $zip->open(dirname(SOURCE_PATH, 1) . '\' . explode('\', SOURCE_PATH)[count(explode('\', SOURCE_PATH)) - 2] . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE); // Some path manipulation here, to actually take the whole "parent" folder of the path passed to the function's parameter

    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY);

    foreach ($files as $file) {
        if (!$file->isDir()) {
            $real = $file->getRealPath();
            $relative = substr($real, strlen($path));

            $zip->addFile($real, $relative);
        }
    }

    $zip->close();
}
 

Моя проблема заключается в том, что при просмотре содержимого zip-файла в WinRAR они отображаются обычно, как и ожидалось, в папках; когда вы извлекаете zip, снова создается целое дерево папок вместе с файлами. Но когда вы переносите zip-файл на сервер linux, на котором размещен интернет-магазин, и извлекаете его, все файлы извлекаются в папку, в которую был загружен zip, как будто zip-файл «сплющен»…

Пожалуйста, взгляните на два видео ниже:

В Окнах

В Linux

Что я сделал не так? Это был первый раз, когда я использовал ZipArchive, поэтому у меня нет большого опыта в этом.

Ответ №1:

Путь к файлу в zip должен использоваться / в качестве разделителя путей, вы можете попробовать код ниже

 function compress(string $path)
{
    $zip = new ZipArchive();
    $zip->open(dirname(SOURCE_PATH, 1) . '\' . explode('\', SOURCE_PATH)[count(explode('\', SOURCE_PATH)) - 2] . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE); // Some path manipulation here, to actually take the whole "parent" folder of the path passed to the function's parameter

    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY);

    foreach ($files as $file) {
        if (!$file->isDir()) {
            $real = $file->getRealPath();
            $relative = substr($real, strlen($path));
            // replace path separator
            $relative = str_replace('\', '/', $relative);
            $zip->addFile($real, $relative);
        }
    }

    $zip->close();
}
 

Комментарии:

1. Вы так правы! Действительно, в этом-то и была проблема! Спасибо вам большое, очень большое! 😀