ダウンロード サンプルファイル (9.6 KB)
Smartyでページ出力時に文字コードを変換する
Smartyには、テンプレートがコンパイルされた後や表示の直前に、任意の関数を実行させる拡張機能があります。文字コードがSJIS以外のデータをCSVファイルでダウンロードしたい場合やサーバー上の制限や管理上の制約などでプログラムの文字コードを変更できない場合などに、Smartyの機能で出力時の文字コードを変換することができます。また、携帯向けサイトではヘッダのContent-Typeに「application/xhtml+xml」が指定されていると、PHPの出力バッファの文字コードを出力文字コードに変換する関数mb_output_handlerが使用できません(mb_output_handlerの仕様で「Content-Type: text/*」の場合しか変換ができないためです)。
このようなXHTMLを利用した携帯向けサイト作成の際には、Smartyの機能を利用して出力文字コードを変換します。本項では、テンプレートをdisplayメソッドやfetchメソッドを経由して呼び出し、表示の際に実行されるアウトプットフィルタという機能を利用して文字コードを変換する機能について説明します。
アウトプットフィルタはSmartyのregister_outputfilterメソッドを使って登録します。アウトプットフィルタは以下のように定義し、Smartyインスタンスに登録します。
// アウトプットフィルタの定義
function 関数名($tpl_output, &$smarty)
{
# 処理
return # 処理結果
}
// アウトプットフィルタを登録
$smarty->register_outputfilter(関数名);
上記コードの「$tpl_output」は処理を行うテンプレート出力オブジェクトになります。「$smarty」はSmartyインスタンスになります。アウトプットフィルタを利用して、前ページのサンプルを元に出力文字コードをSJISにする処理を加えます。
// アウトプットフィルタの定義
function filter2sjis($buff, &$smarty) {
return mb_convert_encoding($buff,"SJIS","UTF-8");
}
// アウトプットフィルタを登録
$smarty->register_outputfilter("filter2sjis");
// テンプレートを表示
$smarty->display("books_sjis.tpl");
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <title>books</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

文字コードがSJISで表示されていることが分かります。
SmartyでCSVファイルをダウンロードする
管理画面の機能でよく実装されているデータのCSV形式でのダウンロード機能を、Smartyを使って実装します。文字コードをSJISにする機能は前項で作成しておりますので、この機能はそのまま使います。CSVで出力する場合は画面表示を伴わないため、displayメソッドではなくfetchメソッドを使ってテンプレート内容をそのまま出力します。ブラウザでそのまま表示するのではなく、テキストファイルとしてダウンロードさせたい場合にはHTTPヘッダの「Content-Type」を以下のように指定します。
header("Content-type: text/octet-stream");
「octet-stream」はMIMEのサブタイプの1つで「application/octet-stream」とすれば特にファイルの種類を意識することなくバイナリ値の転送として扱われます。サンプルではテキスト形式の1つとしてcsvファイルを出力しているため「text/octet-stream」としています。
また、今回のサンプルはHTML以外のファイルにブラウザからアクセスしますのでHTTPヘッダ「Content-disposition」も指定しています。
header("Content-Disposition: 「inline or attachment」 ; filename=[ファイル名]");
「Content-Disposition」で指定する「inline」「attachement」の属性の意味は以下の通りです。
| メソッド名 | 概要 |
| Content-Disposition: inline | 表示する際に同時に内容も即座に表示する |
| Content-Disposition: attachment | ユーザーに何かのアクションを起こさせてから内容を表示する |
Zipファイルや画像ファイルのダウンロードの際などは「attachment」を指定します。サンプルでは「Content-type: text/octet-stream」でダウンロードさせるファイルとしてHTTPヘッダを指定するので「Content-Disposition」では「inline」を指定しています。
# 略
// アウトプットフィルタを登録
$smarty->register_outputfilter("filter2sjis");
// ファイル名の決定
$file_name = date('Ymd_His') . ".csv";
// ファイル名ヘッダ出力
header("Content-Disposition: inline ; filename={$file_name}" );
// MIMEタイプヘッダ出力
header("Content-type: text/octet-stream");
// HTMLを取得
$csv = $smarty->fetch('books_csv.tpl');
// サイズヘッダ出力
header("Content-Length: ". strlen($csv));
// csvデータ出力
echo $csv;
書籍名,発行日
{foreach from=$books key=k item=i}
{$i.title},{$i.published}
{/foreach}
HTTPヘッダ「Content-Disposition」内のファイル名は「年月日時刻」とし、アクセスされた時刻ごとに変わるようにしています。

上記のようにテンプレートと出力パターンを変更することで、Smartyを使ってCSVでのダウンロード機能を実装できます。
この記事は参考になりましたか?
- 目的に応じて適材適所で使うPHPライブラリ連載記事一覧
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
