これを行うには、特定のリソースをアプリケーションコントローラーに読み込むアクションヘルパーを作成します。
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function __construct(array $resources = array())
{
$ this ->_resources = $resources;
}
public function preDispatch()
{
$bootstrap = $ this ->getBootstrap();
$controller = $ this ->getActionController();
foreach ($ this ->_resources as $name) {
if ($bootstrap->hasResource($name)) {
$controller->$name = $bootstrap->getResource($name);
}
}
}
public function getBootstrap()
{
return $ this ->getFrontController()->getParam( 'bootstrap' );
}
}
* This source code was highlighted with Source Code Highlighter .
ブートストラップで初期化します:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initResourceInjector()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_ResourceInjector(array(
'db' ,
'layout' ,
'navigation' ,
));
);
}
}
* This source code was highlighted with Source Code Highlighter .
上記のコードは、リソース、db、レイアウト、ナビゲーションへのリンクを作成します。 つまり、コントローラーから直接アクセスできるようになりました。
class FooController extends Zend_Controller_Action
{
public function barAction()
{
$ this ->layout->disableLayout();
$model = $ this ->getModel();
$model->setDbAdapter($ this ->db);
$ this ->view->assign(
'model' => $ this ->model,
'navigation' => $ this ->navigation,
);
}
// ...
}
* This source code was highlighted with Source Code Highlighter .
このソリューションにより、いくらか単純化されます。初期化オブジェクトからブートストラップを取得してから、リソースを取得する必要がなくなりました。
しかし、このソリューションにはいくつかの問題があります。どのリソースがコントローラーに接続されているかをどのようにして知ることができますか? これをどのように制御できますか?
ここから、コントローラに必要なリソースのプールを作成する決定が続きます。
新しいリソース読み込みアクションヘルパーは次のようになります。
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function preDispatch()
{
$bootstrap = $ this ->getBootstrap();
$controller = $ this ->getActionController();
if (!isset($controller->dependencies)
|| !is_array($controller->dependencies)
) {
return ;
}
foreach ($controller->dependencies as $name) {
if ($bootstrap->hasResource($name)) {
$controller->$name = $bootstrap->getResource($name);
}
}
}
public function getBootstrap()
{
return $ this ->getFrontController()->getParam( 'bootstrap' );
}
}
* This source code was highlighted with Source Code Highlighter .
それでもブートストラップに登録する必要がありますが、今はリソースのリストを指定せずに:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initResourceInjector()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_ResourceInjector();
);
}
}
* This source code was highlighted with Source Code Highlighter .
代わりに、コントローラー自体に必要なリソースのリストを定義します。
class FooController extends Zend_Controller_Action
{
public $dependencies = array(
'db' ,
'layout' ,
'navigation' ,
);
public function barAction()
{
$ this ->layout->disableLayout();
$model = $ this ->getModel();
$model->setDbAdapter($ this ->db);
$ this ->view->assign(
'model' => $ this ->model,
'navigation' => $ this ->navigation,
);
}
// ...
}
* This source code was highlighted with Source Code Highlighter .
これにより、コントローラーが必要とするリソースの明確な理解が得られます。また、各コントローラーは使用するリソースを正確に受け取ります。
リソースローダーに追加できるもう1つの改善点は、依存リソースが見つからなかった場合、例外がスローされることです。
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function preDispatch()
{
$bootstrap = $ this ->getBootstrap();
$controller = $ this ->getActionController();
if (!isset($controller->dependencies)
|| !is_array($controller->dependencies)
) {
return ;
}
foreach ($controller->dependencies as $name) {
if (!$bootstrap->hasResource($name)) {
throw new DomainException( "Unable to find dependency by name '$name'" );
}
$controller->$name = $bootstrap->getResource($name);
}
}
public function getBootstrap()
{
return $ this ->getFrontController()->getParam( 'bootstrap' );
}
}
* This source code was highlighted with Source Code Highlighter .
これにより、依存リソースの理解と追跡が向上します。 リソースはそれらを必要とするオブジェクトによって決定され、リソースが不足すると例外がスローされます。
可能な改善の1つは、各コントローラーに自動的にロードされるリソースのリストを指定することです。 これを実装するには、デフォルトのリストをコントローラーで定義されたリソースとマージする必要があります。 このタスクは読者に任せます。
アクションヘルパー領域は、ZFユーザーによる調査が不十分です。 この投稿で、アクションヘルパーが反復可能な一般的なタスクをどれだけ自動化できるかを示したいと思います。
この記事は、 Matthew Weier O'Phinneyによる記事の一部を翻訳したものです。ZFアクションコントローラー用のシンプルなリソースインジェクターです 。