以前に書いた「zipファイルの中身を解凍させずに読み出す方法」の続編で、内包する画像ファイルをそのまま表示するコードを追加しました。
[PHP] zipファイルの中身を解凍させずに読み出す方法
やりたいこと
zipファイル圧縮された画像の中に含まれる画像をいちいち解凍してWEBページに表示するのではなく、zipファイルのまま画像を取り出して表示するエコシステム。
わざわざ解凍しているとテンプレートとしての一時ファイルなので、その瞬間以外はゴミファイルになります。
また、同じzipデータ内の画像のキャッシュファイルとして、二次利用できそうな気もしますが、そもそもzipファイルとテンプレートファイルという複数の管理をしなければいけなくなるのは、不都合が多いはず。
ソースコード
<?php
namespace readZip;
class proc{
// zipファイルの内部リスト表示
public static function getLists($zipPath){
if(!is_file($zipPath)){return;}
unset($res);
exec("unzip -l ".$zipPath ." | awk '{print $4}'" , $res);
if(count($res) > 6){
$res = array_splice($res , 4,-2);
sort($res);
return json_encode($res , JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
else{
return null;
}
}
// 内部ファイルの中身を取得
public static function getData($zipPath , $filePath){
if(!is_file($zipPath)){return;}
return system("unzip -p ".$zipPath ." ". $filePath);
}
// 画像表示
public static function viewImage($zipPath , $filePath){
if(!is_file($zipPath)){return;}
$info = pathinfo($filePath);
switch($info["extension"]){
case "jpg":
case "jpeg":
header("Content-type: image/jpeg");
break;
case "png":
header("Content-type: image/png");
break;
case "gif":
header("Content-type: image/gif");
break;
default:
return;
}
system("unzip -p ".$zipPath ." ". $filePath);
exit();
}
}
<?php
// zipファイルチェック
if(!isset($_REQUEST["zip"])
|| !is_file($_REQUEST["zip"])){
echo "Set ZIP file path. ex) http://***.php?zip=%zipfilepath";
exit();
}
require_once "readZip.php";
// 画像表示
if(isset($_REQUEST["file"])
&& $_REQUEST["file"]){
\readZip\proc::viewImage($_REQUEST["zip"] , $_REQUEST["file"]);
}
// zip内リスト表示
else{
$phpInfo = pathinfo(__file__);
$lists = json_decode(\readZip\proc::getLists($_REQUEST["zip"]) , true);
for($i=0; $i<count($lists); $i++){
$path = $phpInfo["basename"]."?zip=".$_REQUEST["zip"]."&file=".$lists[$i];
echo "<a href='".$path."'>".$lists[$i]."</a>"."<br>".PHP_EOL;
}
}
使い方
zipファイルのパスをクエリでセットして、view.phpにブラウザでアクセスすると、zip内のファイル一覧が表示されます。
今回は、適当にフリー素材の画像をzipファイルに入れておきました。
表示されたリスト(リンク)をクリックすると、その画像が表示される仕様にしています。
画像以外をクリックしても、何も表示されません。
簡単解説
前回試した時に、php側でexecによるコマンド実行を行なって、バイナリデータの連結に失敗していましたが、今回はsystemコマンドを使って、生データを扱えるようにしています。
ただし、systemコマンドは、コマンド実行時に表示してしまうため、今回はsystemコマンドを実行した直後にexecでプログラムを終了しています。
あとは、前回のreadZipにimage表示用の関数を加えているだけなので、さほど説明は必要ないかと思います。
呼び出し側のview.phpは、zipファイル内の一覧表示と、画像表示のパートに分けてコーディングしておきました。
色々なシステムへの組み込みはさほど難しくないと思いますので、どう扱うかはあなた次第です。