携帯の絵文字出力
文字列中に埋められた「絵文字番号」を本来のコードに変換したい。
絵文字を出力する方法として、
http://www.trekdevel.net/archives/633
が、ほぼ完璧に要件を満たしてくれている。
今回は、以下の制約があるため、自分で実装することにした。
- 文字コードは、Shift_JIS
- 文字列中で絵文字番号のキャリアを指定できない(docomo に固定)
- Zend Framework は使わない
ただし、まだ動作確認ができていないので、不具合を見つけ次第修正していくつもり。
絵文字データベースの取得
「絵文字データベースと相互変換マッピングデータベースのJSONファイルを公開します。 : アシアルブログ」から json ファイルを取得します。
使い方
${emoji(絵文字番号)} の記述を絵文字に変換する。
例えば以下のように、ob_get_contents() を利用すれば、既存のPHPスクリプトを絵文字対応できる。
<?php // 記録開始 ob_start(); // 以後、絵文字入りのHTML記述 ?> <html> <body> 晴れ:${emoji(1)} </body> </html> <?php // 結果を文字列で取得 $html = ob_get_contents(); ob_end_clean(); // (仮) UAでキャリア判定 (docomo, ezweb, softbank) $carrier = "docomo"; // 絵文字番号を絵文字変換して出力 $conv = new EmojiConverter(); echo $conv->convert($html, $carrier);
ソースコード
<?php // 絵文字データを格納するディレクトリ define('PICTOGRAM_JSON_DIR', dirname(__FILE__) . '/pictogram'); /** 文字列中の絵文字番号を、指定したキャリアの絵文字に置換するクラス。*/ class EmojiConverter { private $map; // キャリア間の絵文字番号のマッピングオブジェクト private $emoji; // 絵文字番号を絵文字に変換するオブジェクト private $base = "docomo"; // 基準となるキャリア function __construct() { $fname = $this->base . "_convert.json"; $this->load($fname); } private function load($fname) { $fname = PICTOGRAM_JSON_DIR . '/' . $fname; $json = json_decode(file_get_contents($fname)); $this->map = $json->{$this->base}; } function convert($str, $carrier) { $this->emoji = Emoji::getInstance($carrier); $regex = '/\$\{emoji\(([0-9]+)\)\}/'; $callback = array($this, "replace_emoji"); return preg_replace_callback($regex, $callback, $str); } function replace_emoji($matches) { if (!isset($matches[1])) { return $matches[0]; } $id = $matches[1]; $carrier = $this->emoji->getName(); if ($this->base !== $carrier) { $id = $this->map->{$id}->{$carrier}; } if (!$id) { return $matches[0]; } return $this->emoji->convert($id); } } /** 絵文字番号から絵文字に変換する親クラス */ abstract class Emoji { protected $emoji; protected $name; function __construct() { $fname = $this->getName() . '_emoji.json'; $this->load($fname); } private function load($fname) { $fname = PICTOGRAM_JSON_DIR . '/' . $fname; $this->emoji = json_decode(file_get_contents($fname)); } public static function getInstance($carrier) { switch($carrier) { case 'docomo': return new DocomoEmoji(); case 'ezweb': return new EzwebEmoji(); case 'softbank': return new SoftbankEmoji(); default: return null; } } public function getName() { return $this->name; } abstract public function convert($id); } /** AU の絵文字番号から絵文字に変換するクラス */ class EzwebEmoji extends Emoji { protected $name = 'ezweb'; public function convert($id) { if (!$id) return $id; $code = (array)$this->emoji->ezweb->$id; if (!$code) return $id; return pack("H*", $code['sjis']); } } /** ドコモの絵文字番号から絵文字に変換するクラス */ class DocomoEmoji extends Emoji { protected $name = "docomo"; public function convert($id) { if (!$id) return $id; $code = (array)$this->emoji->docomo->$id; if (!$code) return $id; return pack("H*", $code['sjis']); } } /** ソフトバンクの絵文字番号から絵文字に変換するクラス */ class SoftbankEmoji extends Emoji { protected $name = 'softbank'; public function convert($id) { if (!$id) return $id; $code = (array)$this->emoji->softbank->$id; if (!$code) return $id; return pack("H*", "1B24" . $code['webcode'] . "0F"); } }