複数ファイルのアーカイブをダウンロードさせる時の方法

例えば、複数個の画像ファイルをまとめてダウンロードさせたりする場合、サーバ上でテンポラリディレクトリに画像ファイルをコピーして、それらをアーカイブしてダウンロードさせたりします。 しかし、これだと画像ファイルをいちいちコピーすることになるので、ストレージを圧迫する可能性があるし、ファイル数が多いとコピーに時間がかかります。

そこで、シンボリックリンクを作成し、そのディレクトリ毎アーカイブすることにします。

まず、テンポラリディレクトリを作成します。

$tmp_path = "/tmp/" . uniqid(rand());
$archive_dir = "(指定したいディレクトリ名)";
$tmp_dir = $tmp_path . "/" . $archive_dir;

テンポラリディレクトリまでのパスと、テンポラリディレクトリ名を分けている理由は後述。

次に、作成したテンポラリディレクトリに、画像ファイルのシンボリックリンクを作成します。

// $filelists:画像ファイル名のリスト
// $$image_dir:画像ファイルの格納ディレクトリ
foreach( $filelists as $image_name ) :
    $target = $image_dir . "/" . $img_name;
    $link   = $tmp_dir . "/" . $img_name;
    symlink($target, $link);
}

あとは、このテンポラリディレクトリごとアーカイブします。特に画像ファイルの場合、圧縮してもサイズは余り変わらないので、tar でアーカイブすれば、圧縮処理が無い分、処理が早いです。 tarコマンドのオプションで「h」をつけることで、シンボリックリンクを実体としてアーカイブできます。これがキモですね。

// アーカイブファイルパスを設定
$tar_file = tempnam("/tmp", "DOWNLOAD");

// tarコマンドでアーカイブ
$command  = "tar chf $tar_file -C $tmp_path $archive_dir"; 
system( $command );

この時、tarコマンドのオプションで「-C」をつける。これで、指定したディレクトリに移動してから処理します。 こうすることで、テンポラリディレクトリのフルパスでアーカイブされずに済みます。

あとは、このファイルをダウンロードさせてばOK。