6

次のようなコードを使用して、PHP で 14MB のアーカイブを解凍しようとしています。

    $zip = zip_open("c:\kosmas.zip");
    while ($zip_entry = zip_read($zip)) {
    $fp = fopen("c:/unzip/import.xml", "w");
    if (zip_entry_open($zip, $zip_entry, "r")) {
     $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
     fwrite($fp,"$buf");
     zip_entry_close($zip_entry);
     fclose($fp);
     break;
    }
   zip_close($zip);
  }

私のローカルホストでは、従来の " " では 128MB のメモリ制限で失敗しますAllowed memory size of blablabla bytes exhausted。サーバーには 16MB の制限があります。この制限に収まるようにするためのより良い方法はありますか? これが 128MB を超えるメモリを割り当てなければならない理由がわかりません。前もって感謝します。

解決策: 10Kb のチャンクでファイルの読み取りを開始しました。問題は 1.5MB のピーク メモリ使用量で解決されました。

        $filename = 'c:\kosmas.zip';
        $archive = zip_open($filename);
        while($entry = zip_read($archive)){
            $size = zip_entry_filesize($entry);
            $name = zip_entry_name($entry);
            $unzipped = fopen('c:/unzip/'.$name,'wb');
            while($size > 0){
                $chunkSize = ($size > 10240) ? 10240 : $size;
                $size -= $chunkSize;
                $chunk = zip_entry_read($entry, $chunkSize);
                if($chunk !== false) fwrite($unzipped, $chunk);
            }

            fclose($unzipped);
        }
4

4 に答える 4

5

一度にファイル全体を読み取るのはなぜですか?

 $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
 fwrite($fp,"$buf");

その小さなチャンクを読み取って、ファイルに書き込んでみてください。

于 2010-07-16T08:52:58.123 に答える
1

zipがPHPのメモリ制限よりも少なく、おそらく解凍されたものも同様であるという理由だけで、PHPのオーバーヘッドを一般的に考慮せず、さらに重要なことに、ファイルを実際に解凍するために必要なメモリを考慮していません。 dは、最終的な解凍サイズよりもはるかに大きい可能性があることを期待しています。

于 2010-07-16T08:33:52.160 に答える
0

そのサイズのファイルの場合は、shell_exec()代わりに次を使用した方がよいでしょう:

shell_exec('unzip archive.zip -d /destination_path');

PHP をセーフ モードで実行してはなら、この方法を機能させるには、shell_exec と unzip の両方にアクセスできる必要があります。

更新

コマンド ライン ツールが利用できないことを考えると、スクリプトを作成し、コマンド ライン ツール利用可能なリモート サーバーにファイルを送信し、ファイルを抽出してコンテンツをダウンロードすることしか考えられません。

于 2010-07-16T08:35:31.780 に答える
0
function my_unzip($full_pathname){

    $unzipped_content = '';
    $zd = gzopen($full_pathname, "r");

    while ($zip_file = gzread($zd, 10000000)){
        $unzipped_content.= $zip_file;
    }

    gzclose($zd);

    return $unzipped_content;

}
于 2014-07-06T23:42:12.253 に答える