Sometimes you need to access some resources created inside your bootstrap somewhere deep inside your application. There are two ways to achieve this. First is to use Zend_Registry, and second is to use resources of your bootstrap directly. Before we’ll follow, please ask your self: “Am I really need this?”, because in most cases you don’t need it, so this is a useless post.
So, seems like you really need this useless tip ;)) as you still here, so let’s start. The most known way to achieve this as I told before is Zend_Registry. So for example you can put something like this into your init/bootstrap:
//somewhere in your bootstrap
Zend_Registry::set('myResourceName', $resource);
Then, you can access this $resource anywhere as simple as:
// somewhere outside your bootstrap
$resource = Zend_Registry::isRegistered('myResourceName')
? Zend_Registry::get('myResourceName') : null;
Note that I used Zend_Registry::isRegistered() method to check if specified key exists in the registry at all. Of course if you need to access more than one value, you better use instance of registry to minimize some redundant calls:
$registry = Zend_Registry::getInstance();
$resource_1 = $registry->offsetExists('myResource1')
? $registry->offsetGet('myResource1') : null;
$resource_2 = $registry->offsetExists('myResource2')
? $registry->offsetGet('myResource2') : null;
It was robust and simple. But if you use Zend_Application, then you would like to get access to your Booststrap resources. For those who are not familiar with Bootstrap resources, I would like to make short introduce. There are two types of resources: first is subclasses of Zend_Application_Resource_ResourceAbstract and second are methods with _init prefix of your Bootstrap class. One very important notice, when your resource returns a value, it will run only once, e.g.:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initFoo()
{
$t = microtime();
echo 'Foo (' . $t . ')';
return $t;
}
protected function _initBoo()
{
$t = microtime();
echo 'Foo (' . $t . ')';
}
}
According to example above, $this->bootstrap('Foo'); will echo a string only once and you’ll be able to get $t value, by $this->getResource('Foo') in your Bootstrap class. But as _initBoo() doesn’t return any value it will be called every time (and in this dummy sample will echo string as many times as) $this->bootstrap('Boo') is called.
Let’s assume we have some resource described in our Bootstrap. For example, we want to have access to child values of app from our application configuration:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initConfig()
{
return new Zend_Config((array) $this->getOption('app'));
}
}
Also let’s say that our application.ini has at least following settings:
[production]
#...
app.name = "My Application"
app.admin.email = "ixti@example.com"
app.admin.name = "Aleksey V. Zapparov AKA ixti"
#...
First, for vivid purpose, here’s an example how this resource will work inside Bootstrap:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
// ...
protected function _initLog()
{
// make sure Config resource is initiated first
$cfg = $this->bootstrap('Config')->getResource('Config');
$mail = new Zend_Mail();
$mail ->addTo($cfg->admin->email, $cfg->admin->name);
$writer = new Zend_Log_Writer_Mail($mail);
$writer ->setSubjectPrependText('Errors with ' . $cfg->name);
// Limit log event level for the writer
$writer ->addFilter(Zend_Log::WARN);
$log = new Zend_Log();
$log ->addWriter($writer);
return $log;
}
}
Now, you want to get Config resource somewhere outside your Bootstrap class. To do this you simply need to get an access to your Bootrstap instance, so you’ll be able to get any resource of it with something like:
$admin = $bootrap->getResource('Config')->admin;
Of course if you have an access to your Zend_Application instance it’s not a big deal, as application have an appropriate method getBootstrap(), so you can get your bootstrap by:
$bootstrap = $application->getBootstrap();
But you don’t have a direct access to application within ActionController. Fortunately, FrontController resource sets Boostrtrapbootstrap parameter. So you can access both bootstrap and application from your Contoller, without any additional “dances”:
public class FooController extends Zend_Controller_Action
{
public function init()
{
$front = $this->getFrontController();
$bootstrap = $front->getParam('bootstrap');
$application = $bootstrap->getApplication();
}
}
Pingback: A Simple Resource Injector for ZF Action Controllers – Matthew … | PHP WebDev Insider