Magazine Basic というテーマを使っていますが,<meta name=”description” content=” ・・・の中身が文字化けしているのに気づきました.なぜこんなところが化けていたのに気づいたかというと,Googleの検索結果にリスティングされた自分の記事が化けていたからです.
原因は,テーマ内のdescriptionを生成する関数で,htmlentities()を第2,第3引数なしで使用していたためでした.Magazine Basicの場合は,function.php内のmetaDesc()という関数です.
htmlentitiesはHTMLのエスケープ処理を行う関数(htmlspecialcharsよりもエスケープ対象が多い)ですが,第2,第3引数を省略して使用することができます.第3引数を省略すると,ISO-8859-1をデフォルトのcharsetとして変換してしまうようです.第2引数はXSS脆弱性の観点からも指定したほうが良い(デフォルトの定数はENT_COMPATで,シングルクオートを変換しない)ということで,htmlentities()の正しい使い方は,以下のようになります.
htmlentities($str, ENT_QUOTES, mb_internal_encoding());
ただし,mb_internal_encoding()が適切に設定されている必要があります.もし,ウェブサイトで使用している文字コードが確定しているならば,”UTF-8″などを直接指定してもよいでしょう.
さらに,文章の抽出にあたって,何文字までを抜き出すという部分でもstrlenやsubstrを使っていたりしたので,マルチバイトの文字を適切に処理するよう,mb_strlenやmb_substrに置き換えるなどの措置も必要でした.
#追記:テーマの設定で抜粋文字数を設定しても反映されない場合の対処
Multi-byte 環境で,WP Multibyte Patchのプラグインを導入している場合,抜粋系関数の文字数最大値がこのプラグインの設定値で上書きされます.その場合,テーマの設定で抜粋文字数を設定しても上書きされてしまうので,上記ページで説明されているとおりに,WP Multibyte Patchの設定値を書き換える必要があります.