Smartyを利用したUTF-8化の解決策

SmartyのUTF-8化の解決策の再現方法。
結局、どこが問題あったのかが微妙に不明なままなので、細かく・・・メモしておきます。
PHPのmbstringや、親ディレクトリの[ .htaccess ]などが複雑に絡んでいるかもしれませんが。。。


テスト機と本番機で全然設定が違うのに・・・・テスト機はこの設定じゃないとNG。
php.iniを書き換えるのは抵抗があるので、htaccessで設定

PHPスクリプト設置ディレクトリの phpinfo()

開発機

mbstring.detect_order: auto
mbstring.encoding_translation: Off
mbstring.func_overload: 0(none)
mbstring.http_input: auto
mbstring.http_output: utf-8
mbstring.internal_encoding: utf-8
mbstring.language: Japanese
mbstring.script_encoding: no value
mbstring.substitute_character: no value

本番機

mbstring.detect_order: auto
mbstring.func_overload: 0(none)
mbstring.http_input: auto
mbstring.http_output: euc-jp
mbstring.internal_encoding: euc-jp
mbstring.substitute_character: no value

Smarty テンプレート

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset={$data.html_output}">
<title>{$data.html_title}</title>
</head>
<body>
<div>
テンプレート内に直接記載
</div>
<br>
<div>
PHPからセット -> {$data.comment|nl2br}
</div>
<br>
<div>
{$data.html_output}
</div>
</body>
</html>

※保存はEUCで

UTF-8出力PHPサンプル

テンプレートも、PHPもEUC-JPで保存。(その方がいいらしい・・・)
$smartyをdisplay() または fetch() した直後に regist_outputfilter() が呼び出されて、文字コードの変換を行う。

<?php
mb_language('Japanese');
require_once('lib/PEAR/Smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->template_dir = './';
$smarty->compile_dir = 'lib/templates_c';
$data['html_title'] = 'タイトル';
$data['comment'] = 'PHP側からデータをセット♪';
$smarty->assign('data', $data);
// template(encode) == php(encode)
$smarty->register_outputfilter("output_filter");
$smarty->display("sample.tpl");
//{{{
function output_filter($buff, &$smarty)
{
if (function_exists("mb_convert_encoding")) {
$enc = mb_detect_encoding($buff);
if ($enc != "UTF-8") {
return mb_convert_encoding($buff. "<br><hr>{$enc} - utf-8: outputfilter<br>", "UTF-8", $enc);
}
}
return $buff;
}
//}}}
?>

※保存はEUCで

Smarty フィルタの概要

フィルタの種類・適用タイミング

prefilter:
prefilterは、テンプレートのコンパイル前に実行される。
例えば、SmartyテンプレートをEUC以外で作成している場合、一旦テンプレートをEUCに変換したりするのがこのタイミング。
postfilter
postfilterは、テンプレートのコンパイル後に実行される。
例えば、UTF-8出力やSJIS出力、全カナの半角化あたりはここでも可能。(outputfilterよりタイミングが早い)
outputfilter
outputfilterは、$Smarty->display() や $Smarty->fetch() のいずれかが呼び出された時に実行される。
また、後日調査してみて何か分かれば追記します。