PHPのzip拡張機能を使用してzip圧縮パッケージを処理する場合、 zip_read()とzip_entry_read()は、頻繁に使用される2つの関数です。ただし、多くの開発者は、zip_read()でエントリを繰り返し使用する際に混乱する問題に遭遇し、 zip_entry_read()を介してコンテンツを読み取り、エラーが報告され、空のコンテンツまたは文字化けコードも返されます。何がこれを引き起こしますか?この記事では、理由を詳細に分析し、解決策を提供します。
次のコードを検討してください。
$zip = zip_open('http://m66.net/test.zip');
if (is_resource($zip)) {
while ($entry = zip_read($zip)) {
echo 'ファイルを読む: ' . zip_entry_name($entry) . PHP_EOL;
if (zip_entry_open($zip, $entry)) {
$contents = zip_entry_read($entry);
echo $contents . PHP_EOL;
zip_entry_close($entry);
}
}
zip_close($zip);
}
上記のコードを実行すると、次のエラーが発生する可能性があります。
Warning: zip_entry_read(): supplied resource is not a valid Zip Entry resource in...
または、読み取りコンテンツが空で、予想どおり完全に満たされていません。
この問題の根本原因は通常、次のいずれかです。
ZIP_OPEN()はファイルパスでの通過をサポートしていますが、必ずしもリモートURLをサポートするわけではありません。上記の例で使用されているように、 http://m66.net/test.zipは、PHPがAllow_url_fopenを有効にしているかどうか、および基礎となるzip拡張がストリーミングリソースからのzipデータの正しい読み取りをサポートしているかどうかに依存します。ほとんどの場合、 ZIP_OPEN()には、直接探すことができるローカルファイルが必要です。
zip_entry_read()は、読み取りの長さを指定する必要があります。長さが指定されていない場合、デフォルトで1024バイトを読み取り、ファイルが大きい場合にコンテンツが不完全になります。また、ファイルが空または間違っている場合、直接失敗する可能性があります。
zip_entry_open()を使用してエントリを開くと、後続のzip_entry_read()が失敗した場合は実行されません。さらに、PHPの一部のバージョンには、複数のエントリ間で読み取りを切り替えると、特に圧縮方法がストアまたはデフレートされていない場合、互換性の問題があります。
ZIPエントリが正しく読み取られるようにするには、次の手順に従う必要があります。
$localFile = 'test.zip';
copy('http://m66.net/test.zip', $localFile); // リモートファイルをローカルにダウンロードします
$zip = zip_open($localFile);
if (is_resource($zip)) {
while ($entry = zip_read($zip)) {
$name = zip_entry_name($entry);
echo "ファイルを読んでください: $name" . PHP_EOL;
if (zip_entry_open($zip, $entry)) {
$size = zip_entry_filesize($entry);
$contents = zip_entry_read($entry, $size);
echo "コンテンツ: " . PHP_EOL . $contents . PHP_EOL;
zip_entry_close($entry);
} else {
echo "エントリを開くことができません: $name" . PHP_EOL;
}
}
zip_close($zip);
}
ここにいくつかの重要なポイントがあります:
最初にリモートzipをローカルエリアにダウンロードしてから、 zip_open()を使用してローカルファイルを開きます。
zip_entry_filesize()を使用して、正しい読み取り長を取得します。
zip_entry_open()がtrueを返すかどうかを常に確認してください。
zip_read()を使用してエラーを報告する主な理由は、通常、リソースの開く方法、読み取り長が正しく指定されていないか、リモートパスが適切に処理されないことです。常にローカルファイルパスを使用し、 zip_entry_filesize()でコンテンツを正確に読み取ることをお勧めします。より高い要求がある場合は、より高度で安定したインターフェイスを提供するZiparchiveクラスの使用を検討することもできます。
正しいプロセスを通じて、ZIPファイルの読み取りはより安全で、より安定し、より効率的にすることができます。