2011-07-13 15 views
2

私は、自動抽出のためにサーバーにアップロードされたzipファイルを持っています。zipファイルをフォルダのルートに抽出しますか?

zipファイルの構造は、このようなものです:現在、私はJPGの拡張子を持つすべてのファイルを抽出するには、この機能を持っている

/zip_file.zip/folder1/image1.jpg 
/zip_file.zip/folder1/image2.jpg 
/zip_file.zip/folder1/image3.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 

folder1のファイルをmyFolderのルートに展開する方法はありますか?

理想:

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

PS:競合ファイル名の包み私はファイルのみを抽出したり、上書きしないようにする必要があります。

答えて

3

この小さなコードスニペットを代わりに使用してください。各ファイルのファイル名の前にあるフォルダ構造を削除して、アーカイブの内容全体を基本的に1つのフォルダに抽出します。

ここ
<?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();     
} 
?> 
+5

このソリューションは、さまざまなサブディレクトリに重複した名前のファイルが上書きされます。 – shelhamer

+0

ありがとう@Fabianius –

+0

ありがとうございますhttp://php.net/manual/en/ziparchive.extractto.php#100802ここでは、リソースがどこにあるかを理解しようとすると、 'zip://'プロトコル誰かがそれについてのref urlを持っていますか? – blamb

0

:(私はすべてを管理しようとした)

$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(); 
} 
0

php manual on extractTo()で説明したようにあなたが代わりにZip::extractTozip://構文を使用して行うことができます。あなたは、画像のファイル名と一致する必要があり、それをコピーし

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

上記は、ループの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

重複を確認するのは間違いなく良い解決策です。しかし、なぜファイル名を一意にするためにハッシュアルゴリズムを使用するのですか? ZIPアーカイブに多数のファイルがある場合、各ファイルをハッシュすると時間がかかります。とにかく、元のファイル名を保存するソリューションが望ましいと思います。たとえば、同じファイル名のファイルに角かっこで連続した数字を追​​加することができます。 – Fabianius

+0

連続番号は、誰かが末尾に連続した番号のファイルを付けた場合、重複自体を作成する可能性があります:)。しかし、あなたはハッシュが過度なものになる可能性があるので、パスを 'str_replace'でファイル名に変換する方法を提供しました。 – shelhamer

関連する問題