読者です 読者をやめる 読者になる 読者になる

php5.4で、EUC-JP+Smarty

php5.4でコードの大半がEUC-JP、Smarty1.8xを使用しているモノを触る機会があり、
そこでの現象として、
Smartyのhtml_optionsで、option要素name属性,value属性に入るはずのマルチバイト文字が、
軒並み"つぶれて"しまうというものに出会う。(文字化けというより、あるべき文字列が無くなってしまう)


http://php.net/manual/ja/function.htmlspecialchars.php

現象を起こしていた箇所: htmlspecialchars()

<?php
/**
  * Filename: Smarty/plugins/shared.escape_special_chars.php
  */
function smarty_function_escape_special_chars($string)
{
    if(!is_array($string)) {
        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
        $string = htmlspecialchars($string);
        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
    }
    return $string;
}
?>

解消方法: htmlspecialchars()の第2,3引数の指定

<?php
/**
  * Filename: Smarty/plugins/shared.escape_special_chars.php
  */
function smarty_function_escape_special_chars($string)
{
    if(!is_array($string)) {
        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
        $string = htmlspecialchars($string,ENT_SUBSTITUTE,"eucjp-win");
        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
    }
    return $string;
}
?>

smarty2.xのlastでも、この部分のコードは変わっていない。
原因は、環境の設定が不十分な事にあるように考える。
自分のコードで無かったので、あまり手を入れたくなく手出ししなかったけど
自分だったら、最初にini_set()で環境条件を極力設定してコードを書き進める。

第3引数は、環境側でini_set('default_charset','eucjp-win')な設定にすれば有効になるように思ったのだが、
第2引数の関係か、htmlspecialcharsに伝わってない。

第2引数を環境的に設定すればよかったのだろうか…

UTF-8で統一しとけば関係なさそうな話。