zip圧縮ファイルをphpで処理する場合、 zip_read()関数は、圧縮パッケージのコンテンツを1つずつ読み取るのに役立ちます。再帰的なフォルダー操作のScandir()関数を使用すると、サーバー側のZIPファイルを自動的に減圧し、そのディレクトリ構造を保持する関数を簡単に実装できます。この記事では、これら2つの機能を通じてそのようなスクリプトを構築する方法を詳細に紹介します。
PHP環境にZIP拡張機能が有効になっていることを確認してください。有効になっていない場合は、 php.iniファイルを編集し、次の構成行とcommentを見つけることができます。
extension=zip
次に、Webサーバーを再起動します。
zipファイルを開きます。
zipの各エントリを繰り返します。
エントリがディレクトリかファイルかを判断します。
Scandir()を使用して、カスタム関数を備えたディレクトリ構造を再帰的に作成します。
zipでファイルを宛先パスに書き込みます。
<?php
function createDirRecursive($path) {
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
}
function unzipWithStructure($zipFilePath, $destination) {
$zip = zip_open($zipFilePath);
if (is_resource($zip)) {
while ($zip_entry = zip_read($zip)) {
$entryName = zip_entry_name($zip_entry);
$fullPath = $destination . '/' . $entryName;
// それがディレクトリの場合,作成する
if (substr($entryName, -1) === '/') {
createDirRecursive($fullPath);
} else {
// ファイルが存在するディレクトリを確認してください
$dirPath = dirname($fullPath);
createDirRecursive($dirPath);
if (zip_entry_open($zip, $zip_entry)) {
$fileContent = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
file_put_contents($fullPath, $fileContent);
zip_entry_close($zip_entry);
}
}
}
zip_close($zip);
} else {
echo "開くことができませんZIP書類: $zipFilePath";
}
}
// 使用の例
$zipPath = '/var/www/html/uploads/sample.zip';
$extractTo = '/var/www/html/extracted';
// 関数を呼び出して減圧します
unzipWithStructure($zipPath, $extractTo);
?>
Scandir()を使用して、ターゲットディレクトリ構造が正しく作成されていることをさらに確認します。例えば:
function listAllFiles($dir) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$path = $dir . '/' . $file;
if (is_dir($path)) {
echo "目次: $path\n";
listAllFiles($path);
} else {
echo "書類: $path\n";
}
}
}
listAllFiles('/var/www/html/extracted');
上記のコードを実行した後、すべての減圧ファイルとフォルダーを出力して、簡単にデバッグと検証を行うことができます。
すべてのパスは、アクセスパスを使用して、アクセス許可またはパスエラーを回避する必要があります。
生産環境では、ZIPファイルのソースに注意を払い、ディレクトリトラバーサル攻撃を防止します(たとえば、ZIP Contas ../../ )。
パスは、 RealPath()と組み合わせて正規化できます。
ファイルが大きい場合は、ストリーミング読み取りを使用してメモリオーバーフローを防ぐことをお勧めします。
このスクリプトは、圧縮されたファイルのアップロードと自動的にそれらを解凍するのに適しています。たとえば、ユーザーがM66.net/uploadにマルチレイヤーディレクトリ構造を含むzipファイルをアップロードする場合、背景は上記のスクリプトを介してM66.net/storageディレクトリの完全な構造を直接復元し、サムネールの生成、ウイルスのスカニング、バックアップの作成などのコンテンツをさらに処理できます。
このようにして、コンテンツのアップロードとファイルの初期化のワークフローを大幅に簡素化でき、開発効率を改善できます。