ZIPファイルをPHPで操作する場合、一般的に使用される関数にはzip_open()およびzip_read()が含まれます。これらの2つの機能を組み合わせて使用して、zipファイルを開き、1つずつ入力するエントリを読み取ることができます。ただし、開発者はしばしば問題に遭遇します。zip_read ()を呼び出してエントリを読み取るプロセス中に、プログラムは無限のループに分類され、リソースの使用が過度に使用され、プログラムがクラッシュすることさえあります。
この記事では、zip_read()の無限ループの一般的な原因を説明し、効果的な予防方法を提供することに焦点を当てます。
zip_read()がzipファイルでエントリを読み取ると、内部ポインターを繰り返します。 zipファイル自体が破損している場合、または読み取りを終了する条件が正しく呼ばれない場合、 zip_read()が同じアイテムを繰り返し返し、デッドループになります。
一般的な理由は次のとおりです。
zipファイルが破損しているか、異常な形式があるため、エントリポインターが正しく移動されません。
zipファイルの終わりに判断なしなどの回覧条件判断エラー。
zipリソースは正しく閉じられていないか、ポインターが移動されません。
次の例は、zip_read()を安全に使用してzipファイルでエントリを通過し、無限のループを防ぐ方法を示しています。
<?php
$zipFile = 'http://m66.net/sample.zip';
// 開ける ZIP 書類
$zip = zip_open($zipFile);
if (!is_resource($zip)) {
echo "无法開ける ZIP 書類";
exit;
}
while (($zipEntry = zip_read($zip)) !== false) {
$entryName = zip_entry_name($zipEntry);
// エントリの処理
echo "读取書類条目:$entryName\n";
// 開ける条目
if (zip_entry_open($zip, $zipEntry)) {
$contents = zip_entry_read($zipEntry, zip_entry_filesize($zipEntry));
// コンテンツの処理,たとえば、保存または表示
zip_entry_close($zipEntry);
}
// 知らせ:zip_read() 自動的に次のエントリに移動します
}
// 閉鎖 ZIP リソース
zip_close($zip);
?>
キーポイント:
zip_read()ループを使用する場合、無効なエントリが読み取られないように、条件が!== falseであることを確認する必要があります。
エントリを使用した後、 zip_entry_close()に電話して現在のエントリを閉じて、リソースの漏れを避ける必要があります。
ループが完了したら、 zip_close()を呼び出してzipファイルリソースを閉じます。
zipファイルの整合性と正しい形式を確認します。
zipファイルが有効かどうかを確認してください
ファイルを開く前に、最初にファイルが存在するかどうかを確認し、空のファイルを開いたり、ファイルの破損を避けたりするために妥当なサイズです。
サイクル数を制限します
不確実なファイルに遭遇した場合、最大数のループを設定することにより、デッドループを防ぐことができます。例えば:
$maxEntries = 1000; // 読み取りエントリの最大数
$count = 0;
while (($zipEntry = zip_read($zip)) !== false && $count < $maxEntries) {
// 処理コード
$count++;
}
if ($count >= $maxEntries) {
echo "警告:最大入力制限に達します,可能存在异常書類。\n";
}
他のPHP拡張機能を使用して置き換えます
PHPには、より強力で安全なZIPファイルを操作するZiparchiveクラスもあります。不安定なZIP_READ()が発生した場合は、 Ziparchiveを使用することをお勧めします。
<?php
$zip = new ZipArchive();
$zipFile = 'http://m66.net/sample.zip';
if ($zip->open($zipFile) === true) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$entryName = $zip->getNameIndex($i);
echo "读取書類条目:$entryName\n";
$stream = $zip->getStream($entryName);
if ($stream) {
$contents = stream_get_contents($stream);
fclose($stream);
// コンテンツの処理
}
}
$zip->close();
} else {
echo "无法開ける ZIP 書類";
}
?>
Ziparchiveは、処理時に無限のループの問題を抱えておらず、より柔軟です。
zip_read()を使用する場合は、デッドループを防ぐために戻り値がfalseかどうかを必ず確認してください。
各エントリとzipファイルリソースが正しく閉じられていることを確認してください。
ループエントリの数の上限を設定して、例外ファイルが無限のループを引き起こすのを防ぐことができます。
zip_read()の代わりに、より近代的なziparchiveクラスを使用することをお勧めします。
これらの方法を通じて、 ZIP_READ()を使用するときにPHPが無限ループに陥るという問題は効果的に回避でき、プログラムが安定かつ効率的に実行されるようにします。