トップ «前の日記(2007-06-05) 最新 次の日記(2007-06-12)» 編集

2002|01|02|03|04|05|06|07|08|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|02|03|04|07|

2007-06-06 [長年日記]

_ 起動ファイルのコードのスコープ

どうでもいいけど、ちょっと気になること。

Zend Frameworkでは、起動ファイルにいろいろ初期化コードを書いていくけど、そこで使った変数はグローバル変数になってしまうことになる。たとえば、

$config = new Zend_Config_Xml('/path/to/config.xml');
Zend_Registry::set('config', $config);

とかして読み込んだconfigオブジェクトは、普通はZend_Registryにセットしておいて、必要に応じてZend_Registry::get('config')して使うけれども、実際はアクションコントローラの中とかで、

global $config;

とかすればアクセスできてしまう。かといって、わざわざ、

$config = new Zend_Config_Xml('/path/to/config.xml');
Zend_Registry::set('config', $config);
unset($config);

とまでは書かないよね。

じゃあグローバルスコープじゃないようにしようかと、起動ファイルの中身を、

function main()
{
  // 各種初期化処理
}
main();

とかmain()関数でくくって書けばいいかなーと思ったりしたんだけど、それもいまいちぱっとしない気がする。どうせなら、

class Application
{
  public function __construct()
  {
    $this->_init();
    $this->_run();
  }

  protected function _init()
  {
    //初期化コード
  }

  protected function _run()
  {
    //実行
  }
}
new Application();

までやっちゃった方が融通が利くか(staticメソッドのみで書いて、インスタンス化させずに動かした方がきれいか)。

っつーか、起動ファイルの中身をグローバルスコープでフラットに書いていると、可読性が悪くて嫌になってこない?

_ Zend_Aclのresourceの解決

Zend_Aclで、roleの方はスキーマ定義の段階でだいたい決まることが多いだろうし、それを解決するタイミングもユーザー識別の段階でほぼ確定だろうけど、resourceの方はどうやって解決するのが妥当だろう?

ドキュメントにある例では、resourceを指定せず(すべてのresourceに対して)roleごとに操作権限を設定するようになっているけど、よく使われるのは(すべてのresourceに対する)操作権限を管理するパターンではなく、どのresourceにアクセスできるかを管理するパターンだろう。たとえば、管理ツールには管理者のみがアクセスできる、とか。

そう言う場合、やっぱりmodule=resourceと考えて、Zend_Auth_Plugin_Abstract::preDispatch()あたりで、認証結果から確定したrole+リクエストから抜き出したmodule=resourceとして、$acl->isAllowed()するのが常道かな。module単位よりも細かい単位でアクセス制御したい場合は、function getResourceName($request)みたいなメソッドを用意して、requestから対応するresourceを解決するようにするとか。

ただ、SNSみたいにresourceとroleの関係を動的に解決しなければならないことが多いアプリケーションの場合、Zend_Aclをどう使うのがいいのかはまだ未解決。プラグインとかの共通層では対応が難しそうだから、roleとresourceの関係は抽象化した形で登録しておいて、アクションコントローラの末端でgetResource()とgetRole()を実装して突き合わせるしかないかな。それとも末端でローカルなZend_Aclオブジェクトを生成(=resourceもroleもローカルな定義を作り直す)した方がいいんだろうか。

ちなみに、ようやくZend_Session、Zend_Auth、Zend_Aclを実践的に使ってみているけど、思ったよりもだいぶ使いやすくなっていた。Zend_AuthとZend_Auth_Adapterの関係がちょっとわかりにくかったけど。

_ しょうもないバグを見つけた

Zend_Logでmaskとorしているのを見つけたとき以来のしょーもないバグ。まだこんなのが残っているのか。

ちなみになんでこれを見つけたのかというと、ErrorControllerの中で、

$this->getResponse->setHttpResponseCode(403);

をした場合に、なぜかviewRendererでデフォルトのテンプレートがレンダリングされないという症状にはまったから。「Zend_Controller_Response_Abstract::setHttpResponseCode(403)でisRedirect()がtrueにセットされる」→「Zend_Controller_Action_Helper_ViewRenderer::postDispatch()で、render()するかどうかの条件に!$this->getResponse()->isRedirect()を見ている」という原因ね。