こんにちは。harukです。
今回はSoftBankの絵文字の対処法の基礎的な部分についてです。
絵文字コードは以下のようになっています。
0x1B 0x24($) 【 ? 】 【 X 】… 0x0F
【 ? 】 = G / E / F / O / P / Q
【 X 】 = 0x21~0x7E
【 X 】の部分には、[ < ]や[ ' ]や[ \ ]などが含まれているので多少やっかいです。
入力された絵文字を含む文字列を表示する際などには HTMLエンコード(実体参照化)してあげなければいけませんが、
絵文字の中もエンコードされてしまいます。
(例)
こんにちは(0x1B)(0x24)G>(0x0F)
↓
こんにちは(0x1B)(0x24)G>(0x0F)
となってしまい、4文字の別の絵文字になってしまいます。
対応するにはPHPでは以下のように行います。
function SB_htmlspecialchars($str) { $emoji_range = '[G|E|F|O|P|Q][\x21-\x7E]'; $pattern = '/[\x1B][\x24]'.$emoji_range.'+[\x0F]/'; $matches = array(); $match_count = preg_match_all($pattern, $str, $matches); if (!$match_count) { return _htmlspecialchars($str); } $matches[0][] = ''; $split = preg_split($pattern, $str); $split = array_map('_htmlspecialchars', $split); $htmlstr = ''; foreach ($split as $key => $val) { $htmlstr .= $val.$matches[0][$key]; } return $htmlstr; } function _htmlspecialchars($str) { $encode = mb_internal_encoding(); return htmlspecialchars($str, ENT_QUOTES, $encode); }
さきほどの例文で、注意点が一つあります。
古い機種で、絵文字で終わっている場合に末尾の(0x0F)がつかない端末があります。。。
そのため、受け取った文字列に最初に以下の処理を通しておきます。
/* 末尾に0x0Fがない場合に追加 */ function SBEmoji($str) { $emoji_range = '[G|E|F|O|P|Q][\x21-\x7E]'; $pattern = '/[\x1B][\x24]'.$emoji_range.'+([\x0F]?)$/'; $matches = array(); preg_match_all($pattern, $str, $matches); if (isset($matches[1][0]) && $matches[1][0] === '') { $str .= pack("C*", 0x0F); } return $str; }
こんな感じでSoftBankのエスケープシーケンスでの絵文字を対応しておけば問題はないと思います。
あとは、絵文字の相互変換のために、連続している絵文字を1文字ずつに分けたり、
2バイトの絵文字の対応を行ったり、という処理があるぐらいです。
基礎の部分でしたが、お役に立てれば幸いです。
最後に今年の目標を…「Vodafoneと言わないようにする」
修正(2007/10/19 18:15)
コメントにて指摘があり修正しました。ありがとうございます。
// 修正前 preg_match_all($pattern, $str, $matches); if (count($matches) == 0) { return _htmlspecialchars($str); }
// 修正後 $match_count = preg_match_all($pattern, $str, $matches); if (!$match_count) { return _htmlspecialchars($str); }