CodeZine(コードジン)

特集ページ一覧

WEBシステムの様々な機能をSmartyを使って実装する

目的に応じて適材適所で使うPHPライブラリ(7)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/05/25 14:00
目次

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インスタンスに登録します。

[リスト8]アウトプットフィルタの定義と登録の例
// アウトプットフィルタの定義
function 関数名($tpl_output, &$smarty)
{
    # 処理
    return # 処理結果
}

// アウトプットフィルタを登録
$smarty->register_outputfilter(関数名);

 上記コードの「$tpl_output」は処理を行うテンプレート出力オブジェクトになります。「$smarty」はSmartyインスタンスになります。アウトプットフィルタを利用して、前ページのサンプルを元に出力文字コードをSJISにする処理を加えます。

[リスト9]books_sjis.php(抜粋)
// アウトプットフィルタの定義
function filter2sjis($buff, &$smarty) {
	return mb_convert_encoding($buff,"SJIS","UTF-8");
}
// アウトプットフィルタを登録
$smarty->register_outputfilter("filter2sjis");

// テンプレートを表示
$smarty->display("books_sjis.tpl");
[リスト10]hello_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">
books_sjis.php実行結果
books_sjis.php実行結果

 文字コードがSJISで表示されていることが分かります。

SmartyでCSVファイルをダウンロードする

 管理画面の機能でよく実装されているデータのCSV形式でのダウンロード機能を、Smartyを使って実装します。文字コードをSJISにする機能は前項で作成しておりますので、この機能はそのまま使います。CSVで出力する場合は画面表示を伴わないため、displayメソッドではなくfetchメソッドを使ってテンプレート内容をそのまま出力します。ブラウザでそのまま表示するのではなく、テキストファイルとしてダウンロードさせたい場合にはHTTPヘッダの「Content-Type」を以下のように指定します。

[リスト11]Content-typeの指定
header("Content-type: text/octet-stream");

 「octet-stream」はMIMEのサブタイプの1つで「application/octet-stream」とすれば特にファイルの種類を意識することなくバイナリ値の転送として扱われます。サンプルではテキスト形式の1つとしてcsvファイルを出力しているため「text/octet-stream」としています。

 また、今回のサンプルはHTML以外のファイルにブラウザからアクセスしますのでHTTPヘッダ「Content-disposition」も指定しています。

[リスト12]Content-Dispositionの指定例
header("Content-Disposition: 「inline or attachment」 ; filename=[ファイル名]");

 「Content-Disposition」で指定する「inline」「attachement」の属性の意味は以下の通りです。

Content-Disposition属性
メソッド名 概要
Content-Disposition: inline 表示する際に同時に内容も即座に表示する
Content-Disposition: attachment ユーザーに何かのアクションを起こさせてから内容を表示する

 Zipファイルや画像ファイルのダウンロードの際などは「attachment」を指定します。サンプルでは「Content-type: text/octet-stream」でダウンロードさせるファイルとしてHTTPヘッダを指定するので「Content-Disposition」では「inline」を指定しています。

[リスト13]books_csv.php(抜粋)
# 略
// アウトプットフィルタを登録
$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;
[リスト14]books_csv.tpl
書籍名,発行日
{foreach from=$books key=k item=i}
{$i.title},{$i.published}
{/foreach}

 HTTPヘッダ「Content-Disposition」内のファイル名は「年月日時刻」とし、アクセスされた時刻ごとに変わるようにしています。

books_csv.php実行結果
books_csv.php実行結果

 上記のようにテンプレートと出力パターンを変更することで、Smartyを使ってCSVでのダウンロード機能を実装できます。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:目的に応じて適材適所で使うPHPライブラリ

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5