Извлечь каталог внутри Zip

Я пишу скрипт для извлечения файлов из zip-архива в каталог, в котором находится скрипт.

Вот мой код:

$zip = new ZipArchive;
if ($zip->open('latest.zip') === TRUE) {
    $zip->extractTo('.');
    $zip->close();
    unlink('installer.php');
    echo 'it works!';
} else {
    echo 'failed';
}

Это работает нормально, но есть одна проблема. Застежка-молния содержит дополнительный слой. (zip/каталог/файлы), который извлекает как этот каталог/файлы, а не только файлы.

Есть ли способ удалить этот дополнительный слой?

Спасибо за вашу помощь!

Джоэл Драппер


person Joel Drapper    schedule 13.05.2009    source источник
comment
Будьте осторожны, разрешая пользователям загружать zip-файлы, которые вы впоследствии распаковываете. Вы становитесь уязвимы для zip-бомбы: en.wikipedia.org/wiki/Zip_bomb   -  person Frank Farmer    schedule 29.05.2009


Ответы (1)


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

<?php

// Generate random unzip directory to prevent overwriting
// This will generate something like "./unzip<RANDOM SEQUENCE>"
$pathname = './unzip'.time().'/';

if (mkdir($pathname) === TRUE) {

  $zip = new ZipArchive;

  if ($zip->open('latest.zip') === TRUE) {

    $zip->extractTo($pathname);

    // Get subdirectories
    $directories = glob($pathname.'*', GLOB_ONLYDIR);

    if ($directories !== FALSE) {

      foreach($directories as $directory) {

        $dir_handle = opendir($directory);

        while(($filename = readdir($dir_handle)) !== FALSE) {

          // Move all subdirectory contents to "./unzip<RANDOM SEQUENCE>/"
          if (rename($filename, $pathname.basename($filename)) === FALSE) {
            print "Error moving file ($filename) \n";
          }
        }
      }
    }

    // Do whatever you like here, for example:
    unlink($pathname.'installer.php');

  }

  // Clean up your mess by deleting "./unzip<RANDOM SEQUENCE>/"
}

Я не тестировал этот код, поэтому используйте его на свой страх и риск, кроме того, он может не работать должным образом в системах Windows. Кроме того, ознакомьтесь с документацией по всем функциям, которые я использовал:

person Jake McGraw    schedule 13.05.2009
comment
Спасибо за вашу помощь! Мне не нужно создавать другой каталог, так как я знаю, что каталог, в котором находится скрипт, будет пустым. Я просто хочу извлечь файлы из zip (и случайного бесполезного слоя каталога) в ту же папку, где находится скрипт. - person Joel Drapper; 13.05.2009