ZFアプリケーション内で変数スコープの管理とZend_Registry

前記事で、Zend_Registryの多用には要注意とだけ書いて、自分なりの使い方を書いてなかったのでメモ
http://d.hatena.ne.jp/noopable/20090228/1235784269
とりあえず、基本パターンのおさらい

実行時設定はフロントコントローラーに登録する

http://d.hatena.ne.jp/heavenshell/20090228/1235824839
こちらでご紹介いただいていますが、エントリーポイント()->bootstrap()-> Initializer()という過程で読み込んだアプリケーション全体の設定は、フロントコントローラーに登録するのが無難。
Zend_Controller_front::getInstance()で取得できるインスタンスのスタティック変数に保存される。
これは、ディスパッチャーにコピーされ、アクションコントローラーにコピーされ、アクションコントローラー内では、

<?php
//実行時変数の全取得
$args = $this->getInvokeArgs();
//実行時変数の名前指定取得
$argHoge = $this->getInvokeArg($key);

で取得できる。
これはZFの設計上は実行時設定を安全に受け取るための方策の一つと思われます。
アクションコントローラー内から直接フロントコントローラーの変数を上書きすることもできるが、実際にはディスパッチャーにコピーされているのでその上書きはcopy on writeで参照が切れるので_invokeArgs側には影響しない(いや配列で同じ変数内だから、変更されてしまう。直接フロントコントローラーを呼んで変更するなら、そういう目的がある場合ということで)。
Zend_RegistryもFrontControllerもほぼグローバルなわけだけど、FrontControllerに設定したほうがアプリケーション全体の設定という意味でわかりやすく、取得メソッドも用意されているのでブレがないのでこれが基本になると思う。

リクエストはリクエストオブジェクトから

ユーザーからのリクエストについては、リクエストオブジェクトに保存される。ZFでの王道というか、どこでも$this->getRequest()だけは定義されていて、そこから必要な情報を取得できる。UnitTestを書く場合も、入力ポイントが狭い方が管理しやすいというのもあり、各関数をアトミックにしていくのに必要な考え方だと思う。リクエストオブジェクト内の変数へのアクセサはデフォルト値を与えたりといった基本的な機能が共通して使えるので、isset?みたいな冗長な書き方をある程度回避できたりもする。
すると、リクエストオブジェクトでコンポーネント間のデータ受け渡しに使ったら?というアイデアもあるけれど、それはリクエストの濫用っぽい。リクエストオブジェクトは基本的にルーターから変数をいただくわけだけれど、ルートによっては、ワイルドカードで任意の変数を受け取ってしまうので、アプリケーション内で使用しているのと同じ名前をURLから期せずして受け取ってしまう可能性があり、それをカバーするっていう冗長コードが必要になってしまう。
コントローラーからコントローラーにリクエストオブジェクトで値を受け渡す時は、ある意味、リクエストの偽装的な使い方をしたい場合と考えた方がいい気がする。
つまるところ、リクエストはユーザーからのリクエスト情報が保存されるという原則を逸脱しなければいい。

各種設定はZend_Configに

Zend_Configはアプリケーション設定を構造的に扱うのに適したコンポーネント。コンフィグから読み込んだ後は基本的にreadOnlyで変更するにはちょっとした工夫が必要。データベースに対するアクセス情報その他、アプリケーション設定に関してはZend_Configに格納するのがいい。アクセス方法も多彩に用意されているのと、他のコンポーネントがZend_Config形式の設定データを受け取ってくれるので、ZFでアプリケーションを作るならZend_Configの使いまわしにはすぐに慣れるだろう。

セッション(クッキー代わりにも)

Zend_Sessionは$_SESSIONへのアクセサ。$_SESSIONに名前空間による管理や変数毎のライフタイムなどアプリケーション実装に便利な機能を豊富に提供してくれている。たとえば、素のアプリならクッキーで永続化する情報を保存するような機能をrememberMeで指定することで、セッションのまま使用できる。(ユーザーが多いサービスでの多用はできないが)簡易的に実装するならそれで十分だ。

Zend_Registryはどこで?

コンポーネントを見ると、Zend_Registryをデータストアとして使っている例はよく見かける。クラスのスタティックに保存してもいいケースでZend_Registryを使うと、それがグローバルな永続データとして使っているということが明確になる。Zend_Registryはグローバルで名前空間ルールがないので、名前付けには要注意だが、クラス名やコンポーネント名をPrefixに加えるなどすれば混乱は避けられるかもしれない。
自前のアプリケーションでも同様な使い方になるような気はする。自前のコンポーネント的な空間の中で一意なデータストアを必要とするときなどはZend_Registryの出番だろう。Zend_Registryにコンポーネント別のセグメントを切れればベターだと思うんだが、まぁ名前さえ識別できれば似たようなものだからそれでいいのかもしれないけれど。
Zend_Registryの利点としては、プロファイラーを実装する場合かもしれない。コンポーネント独自のクラス内スタティック変数を使う場合よりもアクセサ仕様を明確にしやすい。Zend_Registryの値の変化を追いかけるプロファイラーを作っておけば、継続的アプリケーションの振る舞いを把握しやすいかもしれない。
たとえば、自己最適化型のキャッシュエンジンを書くとしたら、Zend_Registryの値の変化を集計してキャッシュポリシーを変更するとか。構造化されているがアクセサが用意されていないオブジェクトのハッシュをフラット化してインデックスを作るとか・・・

今のところ、思いつくのはそんな感じ。(最後のは、"はったり"です)