MVC 型の PHP アプリケーション開発フレームワークである cakePHP を使ってます。単なるテンプレートエンジンである以上に、日本に利用者が多い(つまり日本語の情報を見つけやすい)こともあって、とても便利です。
cake-logo


そんな cakePHP を使って作っているアプリケーションで、「TSV(CSV) ファイルをダウンロードさせたい」という機能を実装する方法を紹介します。なまじ View/Controller の組み合わせに慣れてしまうと、TSV(CSV) のような View を無視する機能を cakePHP でどう実装するか、という点に迷いますよね。TSV ファイルを作成する前提で調査結果をまとめました。

結論として View(***.ctp) は用意しません。そして Controller 側に以下のような記述を行います:
function download(){
  $this->autoRender = false; //. Viewを使わない
  Configure::write('debug', 0); //. debugコードを出さない

  //. HTTP ヘッダを TSV 用に変更
  header ("Content-disposition: attachment; filename=test.tsv");
  header ("Content-type: application/octet-stream; name=test.tsv");

  //. TSV 本体を生成する部分
  $tsv = "";
  $items = $this->Item->find('all');
  foreach( $items as $item ){
    //. 日本語部分をシフトJISに変換しながら TSV の一行を作成
    $line = $item['Item']['id'] 
      . "\t" . mb_convert_encoding( $item['Item']['name'], "SJIS" )
      . "\t" . mb_convert_encoding( $item['Item']['body'], "SJIS" )
      . "\n";
    $tsv .= $line;
  }

  print($tsv); //. 生成した TSV を出力
  return;
}

肝として、まず View を使わずに処理を終えたいので、autoRender プロパティを false に変更します。また出力結果に debug コードを出したくないこともあるので、debug レベルを 0 に設定しておきます。 更に TSV ファイルをそのまま(選択肢なしで)ダウンロードさせたいので、HTTP ヘッダをダウンロード用のものに変更しています。

TSV 本体部分のコーディングは出力したい内容によって異なりますが、普通に出力したい内容をタブ("\t")区切りにして1行ずつ生成します。これだけでもいいのですが、もし出力した TSV をそのままエクセルで読み込みたい場合などは、文字コードをシフト JIS にしておく必要がある点に注意が必要です。

生成した TSV を最後に出力して処理終了、です。


cakePHP はとても便利なフレームワークですが、今回のような(ビューを使わない)特殊な処理を行う場合は少し特殊な手順が必要になる、というサンプルです。