第14回 Smartyでケータイサイトを作ってみる - Smarty講座
yossy先生のSmarty講座
Lecutures on PHP
第14回 Smartyでケータイサイトを作ってみる (その3)
書き込みされた絵文字の変換は……
さて続いては、POSTされた掲示板への書き込みをどうするか? です。
方針として、POSTされた内容を以下の手順で変換して、そのデータを管理します。
- <>&"などをエスケープ
- {}をエスケープ
- 絵文字を{emoji}関数に変換する
POSTされた内容を表示する際に、先ほど作成した絵文字変換テンプレート関数{emoji}を使いたいところですが、POSTされた内容をテンプレートファイルにあらかじめ生成しておくなどしないと、そのままでは呼び出すことは出来ません。
前回説明したSmarty3であれば、stringリソースを使って表示することは出来ます。
同様の処理がSmarty2でも出来ないでしょうか?
というわけで、ここではグローバル変数の値をテンプレートとして解析するためのリソースプラグインが公開されているので、これを使ってみます。
上記URLで公開されているソースを、plugins/resource.var.phpという名前で保存してください。
このプラグインの使い方ですが、テンプレートとして解析したい文字列をグローバル変数に入れ、それをSmartyクラスのfetchメソッドに渡します。
すると、変数の内容をテンプレートとして解析、変換した結果が返ってきます。
$emoji_tpl = '{emoji code=hare}';
$emoji = $smarty->fetch('var:emoji_tpl');
これを使うことで、{emoji}関数に置き換えられた書き込みも正しく絵文字に変換されて表示できそうです。
ではPOSTされたデータをエスケープし{emoji}タグへ変換する処理を書いてみます。
htdocs/post.php
1 if($_SERVER['REQUEST_METHOD'] == 'POST'){
2 // エスケープ処理
3 $name = escape($_POST['name']);
4 $content = escape($_POST['content']);
5 $address = escape($_POST['address']);
6
7 // 絵文字をタグに置換
8 $emoji_tbl = EmojiTable::getInstance();
9 $agent = Net_UserAgent_Mobile::singleton();
10 if($agent->isDoCoMo()){
11 $carrier = 'docomo';
12 }
13 elseif($agent->isEZweb()){
14 $carrier = 'au';
15 }
16 elseif($agent->isSoftBank()){
17 $carrier = 'softbank';
18 }
19 else{
20 $carrier = null;
21 }
22
23 $name = mb_convert_encoding($emoji_tbl->toTag($name, $carrier),
'UTF-8', 'SJIS-win');
24 $address = mb_convert_encoding($emoji_tbl->toTag($address, $carrier),
'UTF-8', 'SJIS-win');
25 $content = mb_convert_encoding($emoji_tbl->toTag($content, $carrier),
'UTF-8', 'SJIS-win');
26
27 // 登録(snip)
28 }
29
30 function escape($str)
31 {
32 // <>&をエスケープ
33 $str = htmlspecialchars($str, ENT_QUOTES, 'Shift_JIS');
34
35 // {}をエスケープ
36 mb_regex_encoding('SJIS-win');
37 $str = mb_ereg_replace('{', '{', $str);
38 $str = mb_ereg_replace('}', '}', $str);
39
40 return $str;
41 }
ここでは掲示板の書き込みとして、name,content,addressの3つの値がPOSTされるとします。まず<>&をエスケープしています。Smartyテンプレートで修飾子escapeを呼んでエスケープ処理をしたいところですが、今回は出力するSmartyタグを生成する必要があるので、この時点でエスケープします。そしてSmartyタグのデリミタである{}もエスケープします。
次に先ほど作成したEmojiTableクラスのtoTagというメソッドを呼んでいます。このメソッドで絵文字をSmartyタグの{emoji}へ変換します。そして変換した結果を内部処理コードであるUTF-8に戻しています(EUC-JPを使っている方はここを書き換えてください)。変換した結果をDBなどへ登録する処理へ渡します。
ではタグ変換する処理はどうなるでしょうか? 先ほど作成したEmojiTable.class.phpに処理を追加していきます。
libs/EmojiTable.class.php(先ほどのソースに追記)
1 public function toTag($content, $carrier = null)
2 {
3 if($carrier == 'docomo'){
4 return $this->_docomoToTag($content);
5 }
6 elseif($carrier == 'au'){
7 return $this->_auToTag($content);
8 }
9 elseif($carrier == 'softbank'){
10 return $this->_softbankToTag($content);
11 }
12 else{
13 return $content;
14 }
15 }
16
17 protected function _docomoToTag($content)
18 {
19 if(empty($content)){
20 return $content;
21 }
22
23 $old_content = $content;
24 $new_content = '';
25
26 while(true){
27 if(mb_strlen($old_content) == 0){
28 break;
29 }
30
31 $chr = mb_substr($old_content, 0, 1, 'SJIS-win');
32 $old_content = mb_substr($old_content, 1, mb_strlen
($old_content), 'SJIS-win');
33 $new_content .= preg_replace_callback('/(\xF8[\x9F-\xFC])|(\xF9[\x40-\xFC])/', array($this, '_replaceDocomo'), $chr);
34 }
35
36 return $new_content;
37 }
38
39 protected function _replaceDocomo($matches)
40 {
41 if(empty($matches[0])){
42 return '';
43 }
44
45 $emoji_sjis16 = strtoupper(bin2hex($matches[0]));
46 return isset(self::$_docomo_to_code[$emoji_sjis16]) ?
'{emoji code='.self::
$_docomo_to_code[$emoji_sjis16].'}' : self::UNKNOWN_CHAR;
47 }
48
49 protected static $_docomo_to_code = array(
50 'F89F' => 'hare',
51 'F8A0' => 'kumori',
52 'F8A1' => 'ame',
53 'F8A2' => 'yuki',
54 'F8A3' => 'kaminari',
55 :
56 :
57 );
今回はDoCoMoの絵文字変換処理だけ紹介します(_docomoToTag)。1文字ずつ取得し、正規表現で絵文字かどうかを判別します。ケータイからPOSTされるデータはShift-JISなので、先ほど{emoji}関数で作成したテーブルのコードはそのままでは使えません。なので、Shift-JISのコードに対応したテーブルを用意する必要があります(_docomo_to_code)。DoCoMoの絵文字の範囲をここでは1バイト目がF89F~F8FC、2バイト目がF940~F9FCで判定しています。
この正規表現にマッチした文字をbin2hexで16進文字列化し、かつそれが変換テーブルに登録されていたら{emoji}タグへ置換します。
では、登録したデータを表示したいと思います。先ほど紹介したvarリソースプラグインを用います。
// グローバル変数$name, $address, $contentに書き込まれた内容が格納されているとします
$smarty->assign('name', $smarty->fetch('var:name'));
$smarty->assign('address', $smarty->fetch('var:address'));
$smarty->assign('content', $smarty->fetch('var:content'));
$smarty->display('show.tpl');
これで書き込まれた内容の絵文字タグが変換され、Smartyテンプレート内に記述され、そしてアウトプットフィルタでShift-JISに変換され、正しくケータイにも表示されるようになります。
今回、ケータイ対応のための各キャリアごとの対応の説明など細かい部分は端折りましたが、Smartyでケータイサイトを作成するためのヒントととして活用していただければと思います。
というわけで昨年末に連載再開してから8回、トータルで全14回の連載となりましたSmarty講座も今回で終了となります。 つたない説明で分かりづらいところもあったかもしれませんが、この連載が皆さんのWeb開発のヒントとしてお役に立つことが出来ていたら幸せです。
その他の記事も見る
- 第1回 Smartyの紹介
- 第2回 Smartyを使ってみる(その1:変数編)
- 第3回 Smartyを使ってみる(その2:制御構造編)
- 第4回 Smartyを使ってみる(その3:関数編)
- 第5回 Smartyを使って実用的なページを作ってみる(その1)
- 第6回 Smartyを使って実用的なページを作ってみる(その2)
- 第7回 Smartyの便利な機能を使いこなす(その1:キャッシュ前編)
- 第8回 Smartyの便利な機能を使いこなす(その2:キャッシュ後編)
- 第9回 Smartyの便利な機能を使いこなす(その3:フィルタ編)
- 第10回 Smartyの便利な機能を使いこなす(その4:プラグイン編)
- 第11回 Smartyとフレームワーク(その1:CakePHP編)
- 第12回 Smartyとフレームワーク(その2:Zend Framework編)
- 第13回 次世代のSmarty - Smarty3の紹介
- 第14回 Smartyでケータイサイトを作ってみる
- >>「yossy先生のSmarty講座」一覧ページに戻る
- yossy先生
本名:吉武 正史
パッケージ系ソフトウェア会社で、自然言語処理系の研究やWebアプリケーション、検索連動型広告などの開発に従事。
2006年末にフリーランスとして独立し、現在はPHPによるWeb開発の業務を中心に、コンサルティングや執筆活動などを展開。
サイトURL:http://freeative.jp/





ページのトップへ


GETのままでは検索エンジンのロボットが拾ってくれなかったためにSEO対策として有効だと言われていますね。