私はSymfony 2が好きとは言えないが、Fabienの向かっている方向性が好きだ。
技術者社長としての精力的な活動。日本人ばりにワーカホリックかつ日本人よりレベルが高いと思う、
密結合による不便さの解消とDIの啓蒙(DI「コンテナ」にまで頭がまわってるかやや心配だが)、
他ライブラリの積極的な取り込み(Zend Frameworkに似通ってきたのは良い帰結だと見なす)、
法人をあげた開発体制づくり(進化を追求するあまりサポートが疎かなのは目をつぶる)、
エンタープライズフレームワークを求める姿勢(ディレクトリが深すぎるのはカスタマイズで何とかする)、
等々、欠点や偏りはあるが己の信念に向かって突き進む様は、ただただ感嘆するばかりだ。
PHPカンファレンス2009で「互換性は無いからな!」と言われたにもかかわらず、
結局カスタマイズバリバリのsymfony 1.4を愛用している身としては、
「あ、DebugPDOが無い」「あ、sfFinderが無い」など、細かいところでsymfony資産が使えない時につらくなる。
いっそのことSymfony 2を使ってsymfony 1.4を作れないものかとすら思う。
PEARのポータビリティとZend FrameworkやSymfony 2の現状ニーズ解決能力に、
Railsの「設定より規約」の思想と、(相反するが)カスタマイズ性の高さが加われば、最強じゃないかなーと思う。
パフォーマンスの最大化とデプロイ機能の強化も「最強」の要件だと思ってるけど、それは最悪自分でやる。
まあともかく将来的にはそうふう時代になって、PHP資産を扱いやすくなるであろう。わくわく。
閑話休題。いまの現実的にはsymfony 1の一部を他フレームワークに持ち込んで使うのは困難であるから、
「持ち込みやすい資産」に慣れておく/作っておくか、資産を持ち込まない方法を考えるしかない。
sfParameterHolderという、やや裏方の軽微なクラスがある。ここにもノウハウが凝縮されている。
このファイル自体に依存性は無いので、使いたいならこのファイルだけを設置すればいい。
もちろん、MITライセンスである事を明記した上で。
・・・という訳にもなかなかいかないから、いちいち手書きで実装する事が多い。
配列操作クラスを実装するには配列の直接の操作方法を理解しなければいけない。
以下にその方法を記す。
すべてPHPマニュアルに書いてあるノウハウではあるが、PHPをきちんと触った人にしかわかりにくい内容だと思う。
// 初期化(clear)
$parameters = array();
// 取得(get)
$value = $parameters[$name];
// nullを存在するとみなした上での存在確認(has)
array_key_exists($name, $parameters);
// nullやを存在しないとみなした上での存在確認
isset($parameters[$name]);
// falseやnullや""や0を存在しないとみなした上での存在確認
!empty($parameters[$name]);
// 既定値を伴う取得
// $value = (hasの内容 ? getの内容 : 既定値);
$value = array_key_exists($name, $parameters) ? $parameters[$name] : '既定値';
// 既定値の代入のみ
if (!array_key_exists($name, $parameters)) { $parameters[$name] = '既定値'; }
// 値のリスト取得
array_keys($parameters);
// 削除(remove)
unset($parameters[$name]);
// 代入(set)
$parameters[$name] = $value;
// 配列の上書き(add) 値がnullでもkeyがあれば上書きされる
array_merge($parameters, $add_parameters);
// 上書きはしないが配列に要素を追加する 値がnullでも上書きしない
$parameters += $add_parameters;
// serialize
serialize($parameters);
// unserialize
$parameters = unserialize($serialized);
PHPの構文に足りていないのは、hasとgetの部分であることがよくわかる。
「既定値を伴うget」は、addで代用できることもある。(sfActionのメンバ変数みたいなのに適用するのは微妙)
あるいはperlみたいに ||= が使えれば良かった。
// perl
$array{$name} ||= '既定値';
まあそれでも、既定値の問題は構文糖の問題に過ぎない。
しかし、hasの問題は言語仕様の根幹に関わる問題だと思う。
「何をもってして値がない状態とみなすか」という解釈が異なっており、3通りの答えが存在するからだ。
「PHPが未定義エラーを出さないこと」が定義だとすればarray_key_existsで良い。
「データベースからレコードを取ってきて、無い物は配列の既定値を適用する」なんて場合は、
issetやemptyを型などに応じて使い分けなければならない。つまり、統一的な解はない。
そういった使い分けの利便性まで考えると、あながち三項演算子作戦もデメリットばかりではないのかも知れない。
「3通りの答え」に対応した、リッチな配列操作クラスを作るのも一つの方法論だろう。
そこにはさまざまな配列機能を拡張するという余地も残されている。
しかし、PHPには配列操作クラスは無く、ただひたすら配列関数が連なっているという文化的背景を考慮すると、
あえてクラス化に頼らずに配列のままで答えを求めるのも、あるいは「漢のParameterHolder」と言えるかも知れない。
includeやクラス操作に関するオーバーヘッドを気にしなくて良くなるのも大きな利点だろう。