携帯端末から送信された絵文字入りテキストをデータベースに保存するメモ。
CakePHP(1.2.1.8004)を使います。

docomo、SoftBankの端末から絵文字が含まれたテキストを投稿し、それを保存してみます。

Index

  1. すること、しないこと
  2. 設定
  3. テーブル作成
  4. 絵文字コード定義
  5. モデル・コントローラー・ビューの作成
  6. 絵文字をデータベースへ保存
  7. 表示サンプル
  8. 動作について
  9. ダウンロード
  10. リンク(au絵文字)

すること、しないこと

  • 前回までのように、HTMLの文字コードはutf-8とします。
  • 携帯端末(docomo、SoftBank)から送信された、絵文字が含まれたテキストをデータベースに保存します。
    保存したデータが携帯端末(docomo、SoftBank)で表示されることを確認します。
  • au端末での動作確認は行いません(いま行えません)。

設定

設定は、CakePHPで携帯サイトを作る - 絵文字出力と同じです。

テーブル作成

CakePHPで携帯サイトを作る - ログインページ(1)で作成したデータベースにテーブルを追加します。

SQL:
  1. CREATE TABLE `t_simple_msgs` (
  2.   `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   `user_id` int(10) UNSIGNED NOT NULL,
  4.   `msg` varchar(1000) NOT NULL,
  5.   `created` datetime NOT NULL,
  6.   `modified` datetime NOT NULL,
  7.   PRIMARY KEY  (`id`)
  8. )

t_simple_msgsテーブルは、ログインしたユーザーが投稿したテキストを保存するテーブルです。

絵文字コード定義

絵文字コードは、CakePHPで携帯サイトを作る - 絵文字出力と同様です。

モデル・コントローラー・ビューの作成

t_simple_msgsテーブルを作成後、bakeツールを使って、t_simple_msgsテーブルに関連するモデル・コントローラー・ビューを作成しました。

作成されたコントローラーとビューには、主に次のような変更をしました。

  • ログインしないと投稿できない。
  • 投稿した本人以外変更できないようにする。
  • データをデータベースに保存するときに、絵文字を絵文字コードに変更する。

絵文字をデータベースへ保存

携帯端末から送信された絵文字を絵文字コードに変換して、データベースに保存します。

新規にテキストを登録する場合、次のようにしてみました。

app/controllers/simple_msgs_controller.php 抜粋
PHP:
  1. class SimpleMsgsController extends AppController
  2. {
  3. // ...略
  4.  
  5.   function add()
  6.   {
  7.     if (!$this->isLogin()) {
  8.       $this->redirectPage($this->webroot . 'login');
  9.       return;
  10.     }
  11.     if (!empty($this->data)) {
  12.       $this->checkLoginMobileId();
  13.  
  14.       $this->data['SimpleMsg']['msg'] = convert_to_emoji_code($this->data['SimpleMsg']['msg']);
  15.  
  16.       $this->data['SimpleMsg']['user_id'] = $this->getLoginUserId();
  17.       $this->SimpleMsg->create();
  18.       if ($this->SimpleMsg->save($this->data)) {
  19.         $this->Session->setFlash(__('The SimpleMsg has been saved', true));
  20.         $this->redirectPage($this->webroot . 'simpleMsgs/index');
  21.       }
  22.       else {
  23.         $this->Session->setFlash(__('The SimpleMsg could not be saved. Please, try again.', true));
  24.       }
  25.     }
  26.     $users = $this->SimpleMsg->User->find('list');
  27.     $this->set(compact('users'));
  28.   }
  29. // ...略

convert_to_emoji_code()関数で、絵文字を絵文字コード変換します。

app/config/common_func.php 抜粋
PHP:
  1. /**
  2. * 入力文字列内の絵文字を絵文字コード([[emjI:1]]など)に変換する。
  3. */
  4. function convert_to_emoji_code(&$string)
  5. {
  6.   if (!IS_MOBILE) {
  7.     return $string;
  8.   }
  9.   else {
  10.     include_once('Zend/Json.php');
  11.     $conv_str = null;
  12.     if (UAGENT_KIND == UAGENT_DOCOMO) {
  13.       $carrier = 'docomo';
  14.     }
  15.     else if (UAGENT_KIND == UAGENT_AU) {
  16.       $carrier = 'ezweb';
  17.       $conv_str = mb_convert_encoding($string,'UTF-8','UTF-8,SJIS,EUC-JP');// auはUTF-8に自動変換を試みてから処理
  18.     }
  19.     else if (UAGENT_KIND == UAGENT_SB) {
  20.       $carrier = 'softbank';
  21.     }
  22.     else {
  23.       return $string;
  24.     }
  25.     if (make_utf8_map($carrier,$map)) {
  26.       if ($conv_str) {
  27.         conv_emoji4db($conv_str,$map,UAGENT_KIND,$result);
  28.       }
  29.       else {
  30.         conv_emoji4db($string,$map,UAGENT_KIND,$result);
  31.       }
  32.       return $result;
  33.     }
  34.     return $string;
  35.   }
  36. }
  37.  
  38. function conv_emoji4db(&$string,&$map,$uagent_kind,&$result)
  39. {
  40.   $result = '';
  41.  
  42.   $type_str = 'I';
  43.   if ($uagent_kind == UAGENT_AU) {
  44.     $type_str = 'E';
  45.   }
  46.   else if ($uagent_kind == UAGENT_SB) {
  47.     $type_str = 'S';
  48.   }
  49.  
  50.   $arr = unpack("C*",$string);
  51.   $count = count($arr);
  52.   for ($i=1;$i<=$count;$i++) {
  53.     $check_str = null;
  54.     if (isset($arr[$i+1]) && isset($arr[$i+2])) {
  55.       $s = dechex($arr[$i]) . dechex($arr[$i+1]) . dechex($arr[$i+2]);
  56.       $check_str = pack('H*',$s);
  57.     }
  58.     if ($check_str && isset($map[$check_str])) {
  59.       $result .= '[[emj' . $type_str . ':' . $map[$check_str] .']]';
  60.       $i += 2;
  61.     }
  62.     else {
  63.       $result .= pack('C',$arr[$i]);
  64.     }
  65.   }
  66.   return true;
  67. }
  68.  
  69. /**
  70. * 絵文字のutf-8コードと絵文字番号の対応表を作成する。
  71. */
  72. function make_utf8_map($carrier,&$map)
  73. {
  74.   $map = array();
  75.   $path = PICTOGRAM_JSON_DIR . '/' . $carrier .'_emoji.json';
  76.   if (!is_file($path)) {
  77.     return false;
  78.   }
  79.   $data = file_get_contents($path);
  80.   if ($data === false) {
  81.     return false;
  82.   }
  83.   $emoji = Zend_Json::decode($data);
  84.   $arr =& $emoji[$carrier];
  85.   foreach ($arr as $e) {
  86.     $map[pack('H*',$e['utf-8'])] = $e['number'];
  87.   }
  88.   return true;
  89. }

表示サンプル

docomoとSoftBankの実機から絵文字入りテキストを投稿してみました。

iモードHTMLシミュレータⅡでは、次のように表示されます。
絵文字表示サンプル

docomo端末では、softbank端末から投稿した絵文字の一部がダミーテキストとして表示されています。
softbankの絵文字に対応するdocomoの絵文字がないと、そうなります。

softbankのシミュレータ(ウェブコンテンツビューアー)では、次のように表示されます。
softbankシミュレーター絵文字表示サンプル

動作について

docomoとSoftBankの実機で、絵文字の保存・表示を確認しました。
最近の端末であっても、utf-8のHTMLを表示できる端末であっても、動作しないものがあると思います(なんとなく)。

au端末では絵文字の表示も投稿もできないかもしれません。
いま僕はauの実機をもっていないので、他キャリアで投稿された絵文字が表示されるのか、絵文字を入力して投稿できるのか確認できないのです。

auのシミュレータ(Openwave SDK 6.2)では、<img localsrc="番号">で絵文字を出力する場合、絵文字が表示されます。
その方法を止めたので、シミュレータ(Openwave SDK 6.2)でも、絵文字は表示されていません。

ダウンロード

ダウンロードページへのリンクです。

リンク(au絵文字)

関連投稿

Tags: , , ,

コメントをどうぞ