ポップフライでタグ「symfony」が付けられているもの
symfonyでモバイルの開発をする際に、とても参考になるテクニック満載のスライドです。
この中でdocomo、au、SoftBankのキャリア別にinputタグの入力モードを切り替えるカスタムヘルパーが紹介されていますが、省略されている以降のソースも組んでみました。
mobInputTagHelper.php
<?php
function mob_input_tag($name, $value=null, $options = array())
{
$carrier = sfContext::getInstance()->getRequest()->getAttribute('carrier');
if(isset($options['input_style']) && $input_style = strtolower($options['input_style']))
{
unset($options['input_style']);
switch (strtolower($input_style))
{
case 'kana':
$options["mode"] = 'hiragana';
if($carrier != 'docomo')
{
$options['istyle'] = '1';
$options['format'] = '*M';
}
else
{
$options['style'] .= ';-wap-input-format:"*<ja:h>";-wap-input-format:*M;';
}
break;
case 'hankana':
$options["mode"] = 'hankakukana';
if($carrier != 'docomo')
{
$options['istyle'] = '2';
$options['format'] = '*M';
}
else
{
$options['style'] .= ';-wap-input-format:"*<ja:hk>";-wap-input-format:*M;';
}
break;
case 'alpha':
$options["mode"] = 'alphabet';
if($carrier != 'docomo')
{
$options['istyle'] = '3';
$options['format'] = '*m';
}
else
{
$options['style'] .= ';-wap-input-format:"*<ja:en>";-wap-input-format:*m;';
}
break;
case 'numeric':
$options["mode"] = 'numeric';
if($carrier != 'docomo')
{
$options['istyle'] = '4';
$options['format'] = '*N';
}
else
{
$options['style'] .= ';-wap-input-format:"*<ja:n>";-wap-input-format:*N;';
}
break;
}
}
return input_tag($name, $value, $options);
}
作成したカスタムヘルパーは、オートロードされるlibディレクトリ内にhelperというディレクトリを作りその下に配置。
lib/helper/mobInputTagHelper.php
ヘルパーをテンプレートで使用するには、カスタムヘルパーを宣言してロードする必要があります。
<?php use_helper('mobInputTag') ?>
これでテンプレート内でヘルパー関数が使用できます。
// ひらがな
<?php echo mob_input_tag('name', '', array('input_style' => 'kana')) ?>
// 半角カナ
<?php echo mob_input_tag('name', '', array('input_style' => 'hankana')) ?>
// アルファベット
<?php echo mob_input_tag('name', '', array('input_style' => 'alpha')) ?>
// 数字
<?php echo mob_input_tag('name', '', array('input_style' => 'numeric')) ?>
注意点
上記ソースでのいくつか注意点です。
- format属性には半角カナの指定方法がないため、'hankana'オプション指定時にはとりあえず「M」(全角文字)を指定するようになっています。
- 入力モード以外のstyle属性指定にも対応させるよう、-wap-input-formatの前にセミコロンがデフォルトで入るようになってますが、他の指定がある時のみセミコロンを付けるようにしても良いかも。
- このソースはFireMobileSimulatorで出力切り替えを確認したのみで、実機での動作は未確認です。
本来、各キャリアの仕様上では、
docomo
- iモードHTMLはistyle属性、iモードXHTMLは-wap-input-formatをstyle属性
au
- format属性
SoftBank
- mode属性
ということになっているようなのですが、一部の機種依存問題などがあったりすることもあり、こういう冗長的な書き方がバッドノウハウとしてベターなようです。
この辺り、詳しくはスライド作者ゆどうふさんのブログの説明が参考になります。
携帯XHTMLでの入力モードのまとめと、ちょっとしたハマりどころについて - ゆどうふろぐ
また、携帯仕様の資料として以下の書籍も参考にさせて頂きました。
携帯サイト コーディング&デザイン高木 悠介

ソフトバンククリエイティブ 2008-12-26
売り上げランキング : 805
おすすめ平均

Amazonで詳しく見る by G-Tools
symfonyで出力エスケーピング機能を使っている時に生データを出力したい場合、変数であれば
<?php echo $sf_data->getRaw('name') ?>
で出せますが、オブジェクトの値は同じ方法で出すことができません。
テンプレート内で$sf_dataから一旦退避してとか、やり方を調べていたら以下のようにgetRawValueメソッドを使う取り方がありました。
<?php foreach ($members as $member): ?>
<?php echo $member->getRawValue()->getName() ?>
<?php endforeach; ?>
あー、何とか解決。
symfonyは自分が知らないだけで、こうしたいと思ったことの口は大抵用意されてるのでそれを見つけられるかどうかで書き方に差がでますね。
3日目までは挫折したなりにも以前やったことがあったのですんなりだったが、4日目にしてグっとボリュームが出てきた感じ。
新しく試したキーワードをざっと挙げるだけでも、
- モデルにトリガーメソッドを作成
- パーシャルでフラグメントの整理
- トランザクション
- URLルーティング調整
- カスタムクラス作成
となかなかに盛り沢山。
内容も盛り沢山なので、その分だけわからない点もいくつか出てきた。
例えばInterest.phpのsaveメソッドを修正するところで、いきなり「$this->getQuestion()」が取れてしまうのは何で?schemaの定義に基づいて、modelが関連するQuestionオブジェクトも取得してくれてるってことなのかな。その辺りの自動で済ませてくれている部分が把握できてないと、重複してわざわざ取りに行くようなコードを書いてしまいそう。
ルーティングはかなり柔軟性が高そうで良さげですね。この恩恵を受けるために、テンプレート上のリンクはlink_toヘルパを使うようにすることが大事そう。
カスタムクラス作成でやったタイトルのストリップ処理は、日本語タイトル用にurlencodeするように変えたりしていましたが思うように動いてくれませんでした。これもちょっと課題。
symfonyを入り口近辺でちょろちょろ試してはいたものの、ある程度まとまった知識が欲しいと感じ始めていたので、以前から取り組んではすぐ挫折していたaskeetに再びやることにしました。最低限、24日目まで通してやることが目標。
ちなみにsymfonyバージョンは1.0.19。今から始めるなら1.2系がスジなんでしょうが、askeetチュートリアルもDefinitive Guideも日本語訳が揃っている1.0系に有難く頼らせて頂きたいということで・・・。
1日目
環境構築やプロジェクト、アプリケーションの作成など。
Subversion周りの作業など関係無いところはスキップして、とりあえずさくっと終了。
2日目
DB周りの作業をざーっと行う。
$ symfony propel-generate-crud frontend question Question
上記コマンドでCRUDジェネレータを実行するところで、「Questionモジュールが無い」とエラーになりました。そういえばmodule作成する箇所が無かったような・・・。
というわけで、questionモジュールも先に作成しておきます。
$ symfony init-module frontend question
3日目
レイアウトやテンプレートの変更、ルーティング調整、バッチファイルからのテストデータ取り込みなど。
以下、感じたこと。
- ORMの恩恵受けられるようなDB設計を考慮することが大事。
- ジェネレータでベース作って、不要なアクション・テンプレートをクリーンアップしていくという流れがやっぱり基本?
- css落としてきたけど、なんだかレイアウトずれてるんですが・・・。とりあえず無視。
ひとまず今日はここまで。
ORMは便利だろうけど、パフォーマンスが気になるとかSQLが全部目に見える状態で作りたいとかいう話もあったりして、直接PDO経由でDB操作をしたい場合にどうすれば良いのか試してみました。
DSN情報を設定ファイルに記述。
apps/appname/config/app.yml
all:
db:
dsn: mysql:host=localhost;dbname=test
user: root
pass: pass
DB接続クラスを作成。
lib/dbConnection.class.php
<?phpclass dbConnection
{
static private $PDOInstance; protected function __construct()
{
$dsn = sfConfig::get('app_db_dsn');
$user = sfConfig::get('app_db_user');
$pass = sfConfig::get('app_db_pass');
self::$PDOInstance = new PDO($dsn, $user, $pass);
}
public static function getConnection()
{
if(!self::$PDOInstance)
{
new self();
}
return self::$PDOInstance;
}
}
actionなどからコネクション取得。
$conn = dbConnection::getConnection();
で、あとはこのコネクション使っていろいろと、ていう感じで動かしてみていたのですが、おいおい調べていたら自作せずともデフォルトのDB設定でPDO接続を指定できてしまうことを知りました・・・。
config/databases.yml
all:
pdocon:
class: sfPDODatabase
param:
dsn: mysql:host=localhost;dbname=test
dbtype: mysql
database: test
username: root
password: pass
actionからコネクション取得。
$conn = $this->getContext()->getDatabaseConnection('pdocon');
action以外から取得。
$conn = sfContext::getInstance()->getDatabaseConnection('pdocon');
なるほど、こっちの方が簡単。
動的にDB接続先を切り替えたりといったこともやってみたかったりするので、それぞれの使い勝手も含めて引き続き調べてみたいと思います。
まだ動かして間もないですが、少しずつsymfonyに慣れてきた気がします。

