勉強したことのメモ

webプログラマが勉強したことのメモ。

PHPで複数のファイルをまとめてzipファイル化し、ダウンロードさせる方法

   

PHPで複数のファイルをまとめてzipファイル化し、ユーザーにダウンロードさせたい。また、それとは別に特定のディレクトリを丸ごとzipファイル化し、こちらもダウンロードさせたい。以下に2つの対応方法をメモ。

 

複数のファイルをzipファイル化

//zip圧縮したいファイル一覧
$file_list = array(
    './index.html',
    './test.css',
    './test.js',
    './test.jpg',
);

//zipインスタンス作成
$zip_obj = new zipArchive($file_list);

//一時ファイル名前とパス
$zip_name = date('Ymdhis') . '.zip';
$zip_path = '/public_html/' . $zip_name;

//一時ファイルを作成
$result = $zip_obj->open($zip_path, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
if( $result !== true ){
    echo 'error';
    exit;
}

//zipにファイルを追加
foreach ($file_list as $file) {
    $file_name = basename($file);
    $zip_obj->addFromString($file_name, file_get_contents($file));
}
$zip_obj->close();

//ダウンロードさせる
header('Content-Type: application/zip; name="' . $zip_name . '"');
header('Content-Disposition: attachment; filename="' . $zip_name . '"');
header('Content-Length: '.filesize($zip_path));
echo file_get_contents($zip_path);

// 一時ファイル(zipファイル)の削除
unlink($zip_path);
exit();

ダウンロードさせる前の時点までの処理でメモリ消費量を測定したところ、ファイルの合計サイズとほぼ同等のメモリを消費していた。テストした際はファイル合計サイズが20MBでメモリ消費量もほぼ同等だった。

画像や動画ファイルをこの方法でzipファイル化する場合、メモリ消費量がひどいことになりそう。その際はphp.iniのmemory_limitの値に注意する。

 

特定ディレクトリを丸ごとzipファイル化

//zip化したいディレクトリ
$target_path = '/public_html/zip_dir';

//zipファイル名
$zip_name = 'zip_dir.zip';

//zipファイルの一時保存場所
$zip_path = '/public_html/' . $zip_name;

//zipファイル作成
chdir($target_path);
exec("zip -r {$zip_path} .");

//ダウンロードさせる
header('Content-Type: application/zip; name="' . $zip_name . '"');
header('Content-Disposition: attachment; filename="' . $zip_name . '"');
header('Content-Length: '.filesize($zip_path));
echo file_get_contents($zip_path);

//zipファイルを削除
unlink($zip_path);
exit();

こちらもメモリ消費量を計測したところ、ファイルの合計サイズは20MBに対してメモリ消費量は1KB未満だった。また、参考サイトによると処理速度もこちらの方法の方が速いみたい。

 

所感

メモリ消費量や処理速度を見た限りでは基本的にディレクトリ丸ごとzipファイル化するのが良さそう。

 

参考サイト

https://arts-factory.net/zip/

https://blog.ver001.com/php-zip-archive/

 - PHP

  関連記事

MySQLiでSELECT文

MySQLiでSELECT文 ■データ +--+------+ | id | p ...

cronの設定方法

cronを設定してみたので方法をメモ。 まずcronで動かすPHPを作成。 ■c ...

Basic認証がかかっているファイルをPHPで認証突破と取得

Aというサイトにあるベーシック認証がかかっているディレクトリ内のファイルを、Bと ...

FLASHから受信した画像をPHPで保存し、サムネイルも作る

■参考サイト ・FLASH http://www.ilovex.co.jp/bl ...

PHPで画像のアップロード

<php define('IMAGES_DIR', dirname($_S ...

composerでmonologとTwigをインストール

「composerで○○をインストール」というのをよく見かけるがcomposer ...

PHPでyoutubeから更新分の情報を取得する(スクレイピング)

「○○のサイトから自動更新分を持ってきて 自サイトに反映させらへん?」と以前に聞 ...

no image
PHPでもキャッシュで画像が表示されない

ここみたいにキャッシュの影響と考えられるケースが発生した。 結果的にキャッシュっ ...

ユーザーエージェントなどユーザー情報を取得する方法

上からUA、IP、ホスト名を取得。 $ua = $_SERVER['HTTP_U ...

ゼロ詰め(ゼロパディング)の逆はゼロサプレス

ゼロパディングしている日付のゼロの部分を排除したかった。ただ、どうやって調べたら ...