Извлечь файлы в виде zip-файла в корневой каталог? - PullRequest
2 голосов
/ 13 июля 2011

У меня есть zip-файл, загруженный на сервер для автоматической распаковки.

конструкция zip-файла выглядит следующим образом:

/zip_file.zip/folder1/image1.jpg
/zip_file.zip/folder1/image2.jpg
/zip_file.zip/folder1/image3.jpg

В настоящее время у меня есть эта функция для извлечения всех файлов с расширением jpg:

$zip = new ZipArchive();
    if( $zip->open($file_path) ){
        $files = array();
        for( $i = 0; $i < $zip->numFiles; $i++){
            $entry = $zip->statIndex($i);
            // is it an image?  
            if( $entry['size'] > 0 && preg_match('#\.(jpg)$#i', $entry['name'] ) ){
                $f_extract = $zip->getNameIndex($i);
                $files[] = $f_extract;
            }
        }
        if ($zip->extractTo($dir_name, $files) === TRUE) {
        } else {
            return FALSE;
        }

        $zip->close();
    }

Но, используя функцию extractTo, она извлекается в myFolder как ff:

/myFolder/folder1/image1.jpg
/myFolder/folder1/image2.jpg
/myFolder/folder1/image3.jpg

Есть ли способ извлечь файлы из папки 1 в корень myFolder?

Ideal:

/myFolder/image1.jpg
/myFolder/image2.jpg
/myFolder/image3.jpg

PS: в случае конфликта имени файла Мне нужно только не извлекать или перезаписывать файл.

Ответы [ 3 ]

4 голосов
/ 13 июля 2011

Используйте этот маленький фрагмент кода вместо.Он удаляет структуру папок перед именем файла для каждого файла, так что все содержимое архива в основном извлекается в одну папку.

<?php
$path = "zip_file.zip";

$zip = new ZipArchive();
if ($zip->open($path) === true) {
    for($i = 0; $i < $zip->numFiles; $i++) {
        $filename = $zip->getNameIndex($i);
        $fileinfo = pathinfo($filename);
        copy("zip://".$path."#".$filename, "/myDestFolder/".$fileinfo['basename']);
    }                  
    $zip->close();                  
}
?>
0 голосов
/ 13 июля 2011

Вы можете сделать это, используя синтаксис zip:// вместо Zip::extractTo, как описано в руководстве php для extractTo () .

Вы должны соответствовать имени файла изображенияи затем скопируйте его:

if ($entry['size'] > 0 && preg_match('#\.(jpg)$#i', $entry['name'])) {
  copy('zip://' . $file_path . '#' . $entry['name'], '/root_dir/' . md5($entry['name']) . '.jpg');
}

Вышеприведенный код заменяет ваш оператор for цикла if и делает ваш extractTo ненужным.Я использовал хэш md5 исходного имени файла, чтобы создать уникальное имя.Крайне маловероятно, что у вас возникнут какие-либо проблемы с перезаписью файлов, поскольку коллизии хешей встречаются редко.Обратите внимание, что это немного сложная задача, и вместо этого вы можете сделать str_replace('/.', '', $entry['name']), чтобы создать новое уникальное имя файла.

Полное решение (измененная версия вашего кода):

<?php
$zip = new ZipArchive();
if ($zip->open($file_path)) {
  for ($i = 0; $i < $zip->numFiles; $i++) {
    $entry = $zip->statIndex($i);
    // is it an image?
    if ($entry['size'] > 0 && preg_match('#\.(jpg)$#i', $entry['name'])) {
      # use hash (more expensive, but can be useful depending on what you're doing
      $new_filename = md5($entry['name']) . '.jpg';
      # or str_replace for cheaper, potentially longer name:
      # $new_filename = str_replace('/.', '', $entry['name']);
      copy('zip://' . $file_path . '#' . $entry['name'], '/myFolder/' . $new_filename);
    }
  }
  $zip->close();
}
?>
0 голосов
/ 13 июля 2011

Здесь: (я пытался управлять всем)

$zip = new ZipArchive();
if( $zip->open($file_path) ){
    $files = array();
    for( $i = 0; $i < $zip->numFiles; $i++){
        $entry = $zip->statIndex($i);
        // is it an image?  
        if( $entry['size'] > 0 && preg_match('#\.(jpg)$#i', $entry['name'] ) ){
            $f_extract = $zip->getNameIndex($i);
            $files[] = $f_extract; /* you man want to keep this array (use it to show result or something else) */

            if ($zip->extractTo($dir_name, $f_extract) === TRUE) {
                $solid_name = basename($f_extract);
                if(strpos($f_extract, "/")) // make sure zipped file is in a directory
                {
                    if($dir_name{strlen($dir_name)-1} == "/") $dir_name = substr($dir_name, 0, strlen($dir_name)-1); // to prevent error if $dir_name have slash in end of it
                    if(!file_exists($dir_name."/".$solid_name)) // you said you don't want to replace existed file
                        copy($dir_name."/".$f_extract, $dir_name."/".$solid_name); // taking file back to where you need [$dir_name]
                    unlink($dir_name."/".$f_extract); // [removing old file]
                    rmdir(str_replace($solid_name, "", $dir_name."/".$f_extract)); // [removing directory of it]
                }
            } else {
                 echo("error on export<br />\n");
            }
        }
    }


    $zip->close();
}
...