ファイルのダウンロード処理をおこないたいときにテンプレートエンジンを使っている場合、どんな具合にプログラムを書けばよいか迷うことがよくある。フレームワークを使っていない場合はプログラム内にダウンロード処理を直書きしてしまうけれど、フレームワーク使用時は直書きするのはなんとなく美しくない。やっぱり通常通りの処理を通過して、テンプレート内だけで処理できればスマートだと思っている。Smartyの場合だが、今回はテンプレートファイルの最初にこんな具合におまじないを記述することでダウンロード処理を実現できた。
{php}
header(“Cache-Control: public”);
header(“Pragma: public”);
header(“Content-Type: application/csv”);
header(“Content-Disposition: inline; filename=data.dat”);
header(“Content-Transfer-Encoding: binary”);
header(“Accept-Ranges: none”);
{/php}
キャッシュ制御系はSSL使用時のIEバグ対策。Content-type、Content-Dispotion、Content-Transfer-Encodingは適宜指定。実際にダウンロードさせたい部分は、この後ろに記述すればよい。
でも、実はヘッダ的には一つ足りないんだと思う。それはダウンロードさせる容量Content-Lengthだ。この記述が必要なら、上記の記述の前に事前にダウンロードデータを以下のように記述して、容量を計算して出力すればいいかもしれない。
{capture name=download}
(ダウンロードさせたいデータを記述)
{/capture}
{header_content_length var=$smarty.capture.download}
いったん出力データを変数に格納して、別途ヘッダ出力用のカスタム関数(header_content_length)を用意しておいてそれに食わせてやればいい。カスタム関数が必要でしたら・・・各自でどうぞ(今回は作らなくても動いてくれたので作らなかった)。