勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

PHPを用いてフォームからzipファイルをアップロードしサーバ上で解凍(展開)させる方法

   2024/01/16  PHP

formからzipファイルをアップロードしサーバ上で解凍(展開)するという一連の処理をPHPで行いたい。また、アップロードしたzipファイルは削除、解凍したファイルは同名にならないよう指定したディレクトリ内に展開したい。以下に実装方法をメモ。

 

HTML部分

<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="POST" enctype="multipart/form-data">
    <input type="file" name="zip">
    <input type="submit">
</form>

 

PHP部分

<?php
$dir = __DIR__ . '/';

//ファイルが送信された場合
if( $_FILES['zip']['size'] > 0 ){

    $zip_name = md5(uniqid(rand(), true)) . '_' . time();
    $zip_file = $zip_name . '.zip';

    //サーバにアップロード
    if( move_uploaded_file($_FILES['zip']['tmp_name'], $dir . $zip_file) ){

        $zip = new ZipArchive;
        if($zip->open($zip_file) === TRUE){
            $zip->extractTo($dir . $zip_name);
            $zip->close();

            echo 'OK';

            //zipファイルの削除
            unlink($zip_file);

            //展開されたフォルダ内にあるディレクトリを検索
            $dirs = scandir($dir . $zip_name . '/');

            //ディレクトリを決め打ち(0->'.', 1->'..'になる)
            $tmp_dir = $dir . $zip_name . '/' .  $dirs[2] . '/*';

            foreach(glob($tmp_dir) as $file){
                if(is_file($file)){
                    var_dump($file);
                }
            }

        }else{
            echo '解凍エラー';
        }

    }else{
        echo 'アップロードエラー';
    }

}
?>

基本的にはコメントの通りだがファイルが送信された場合にサーバにアップロードし、zipファイルを解凍。その後、zipファイルは削除し指定したディレクトリ内に展開する。展開したディレクトリ内にあるファイルを検索し、var_dumpでファイル名を出力する。

また、ZipArchveクラスに関してはリファレンスを参照

 

注意点

ファイルサイズに注意する

zipファイルでアップロードするのでzip内に複数のファイルが入っているケースが多いと思われ、結果としてファイルサイズが大きくなりそう。

なのでphp.ini側のアップロードサイズ上限やサーバ側のHDDもしくはSSD容量に注意する必要がある。

zip側でフォーマットを決めておく必要がある

今回はとりあえずPHPでzip解凍するところまで検証したかったので、適当なテキストファイルをフォルダに突っ込み、そのフォルダをzip圧縮した。これが例えば多重構造のフォルダになっていたりすると処理が非常に面倒くさそう。

なので多重構造は禁止だとか、アップロードする側にもある程度フォーマットを決めておく必要あり。

 - PHP

  関連記事

PHPで画像にロゴをつける

フォームから送られてきた画像にロゴをつけたかった。 結論としてclass.upl ...

PHPのfor文とforeach文

ループ処理の際、forとforeachのどっちでもいけそうな場合、 特にどっちを ...

Cookieをできるだけ長い期間保存する方法

あるシステムの中でCookieを可能な限り長い期間保存したいというリクエストを受 ...

PHP / MySQLで2038年問題の対策

先日打ち合わせの際に「タイムスタンプを使ってユニークキーに云々~~」といったよう ...

メールサーバーを構築せずにGmailのSMPTを使ってPHPでメール送信

メールサーバーが立てられなかったり、無料サーバーのため使えなかったりといった場合 ...