Quick Start to Zend_Application_Bootstrap
We added Zend_Application to Zend Framework starting in version 1.8.0. The intent behind the component was to formalize the application bootstrapping process, and provide a simplified, configuration-driven mechanism for it.
Zend_Application works in conjunction with
Zend_Application_Bootstrap, which, as you might guess from its
name, is what really does the bulk of the work for bootstrapping your
application. It allows you to utilize plugin bootstrap resources, or define
local bootstrap resources as class methods. The former allow for
re-usability, and the latter for application-specific initialization and
configuration.
Additionally, Zend_Application_Bootstrap provides for
dependency tracking (i.e., if one resource depends on another, you can
ensure that that other resource will be executed first), and acts as a
repository for initialized resources. This means that once a resource has
been bootstrapped, you can retrieve it later from the bootstrap itself.
How it works
Now that you know what it does, let's jump into the basics.
If you use the zf command-line tool provided with Zend
Framework to generate your project ("zf create project"),
you'll get a bootstrap and a default configuration right out of the gate.
This includes the following files in the tree:
application/ |-- Bootstrap.php | `-- configs/ | | `-- application.ini
The Bootstrap.php file will contain the class
Bootstrap which extends
Zend_Application_Bootstrap_Bootstrap; this class will be empty
at first. The application.ini file will contain the following:
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH \"/../library\"
bootstrap.path = APPLICATION_PATH \"/Bootstrap.php\"
bootstrap.class = \"Bootstrap\"
appnamespace = \"Application\"
resources.frontController.controllerDirectory = APPLICATION_PATH \"/controllers\"
resources.frontController.params.displayExceptions = 0
[staging : production]
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
Zend_Application runs in three stages. First, it initializes
the PHP environment, using INI settings from your configuration if provided,
and setting up the include_path and autoloading. Second, it
initializes and executes the bootstrap class. Finally, it then "runs" the
application (by calling the bootstrap's run() method).
Configuration Settings
What we see in the above listing is a set of:
- PHP initialization settings (here, they indicate whether or not to display errors)
include_pathsettings- Settings that indicate the name and location of the bootstrap class
- Application resource settings
The phpSettings key accepts any php.ini keys as
subkeys, and these key/value pairs will be passed to ini_set.
This can be useful when you need to either ensure specific INI settings are
made, particularly when you want them to vary based on environment. (In the
example above, display_errors is enabled in testing and development, but
disabled otherwise.)
When it comes to the include_path and autoloading, probably the most often
asked question is, "How do I add namespace prefixes for code other than ZF
to the autoloader?" This can be done easily in the configuration file using
the autoloaderNamespaces key, and appending namespace prefixes
to it:
autoloaderNamespaces[] = \"Phly_\"
Regarding the bootstrap class and file location, typically the defaults will
be fine. However, if you want to specify a custom name -- for instance, to
provide a class prefix -- or perhaps if your default module is in a
subdirectory, you can notify Zend_Application of this via the
bootstrap.class and boostrap.path settings:
bootstrap.class = \"Application_Bootstrap\"
bootstrap.path = APPLICATION_PATH \"/modules/application/Bootstrap.php\"
Getting started with Bootstrap Resources
Now we finally get to the true fun: the bootstrap resources themselves.
Yes, I'm aware I'm glossing over the "appnamespace" setting; I'l cover that at another time.
Bootstrap resources may be one of two things:
- A protected method in the bootstrap class prefixed with "_init"; e.g., "protected function _initFoo()"
- A class implementing
Zend_Application_Resource_Resource
In the former case, _init*() methods, each will be executed in each request. In the latter, only those that you specify in your configuration will be executed, allowing you to selectively choose which of the various shipped resource plugins (or those you have written yourself!) will be used.
In the case of the default configuration, only the "frontcontroller"
resource plugin will be used, corresponding to
Zend_Application_Resource_Frontcontroller. As of the upcoming
1.10 release, you can pick and choose from the following additional resource
plugins as well:
- Cachemanager
- Db
- Dojo
- Layout
- Locale
- Log
- Modules
- Multidb
- Navigation
- Router
- Session
- Translate
- View
Each has its own configuration options, documented in the manual.
Writing Resource Methods
Writing your own resource methods is trivial: you simply create the method, and do some work. You then have the option of returning a value; if you do, it will be stored within the bootstrap so that you may retrieve it later. As an example:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initRegistry()
{
$registry = new Zend_Registry();
return $registry;
}
}
If we wanted to retrieve the registry later, we could do so using the
bootstrap's getResource() method:
$registry = $bootstrap->getResource('Registry');
Note that we pass the name of the method minus the "_init" prefix; this "short name" is how the resource is referred to within the bootstrap, and how you will refer to it later.
Now, let's say you have a resource that depends on your "Registry"
resource; for instance, let's say you want to create a
Zend_Currency object, and pass it to the registry.
Zend_Application_Bootstrap was designed to handle this very
situation, and institutes some powerful dependency tracking (this is, in
fact, why the initialization methods are protected; it prevents them being
called directly). Simply call the bootstrap() method with the
name of the resource to initialize. Additionally, the
getResource() method can then be used to retrieve the value
registered for that resource. As an example:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initCurrency()
{
$this->bootstrap('Registry');
$registry = $this->getResource('Registry');
$currency = new Zend_Currency('$');
$registry['Zend_Currency'] = $currency;
return $currency;
}
protected function _initRegistry()
{
$registry = new Zend_Registry();
return $registry;
}
}
What will happen is this:
-
Zend_Applicationwill callbootstrap()with no arguments, which loops through the internal resource methods first, and then any configured resource plugins. - The bootstrap will execute the
_initCurrency()method - It sees the
bootstrap()call, and executes it -
The
bootstrap()call executes the_initRegistry()method, storing aZend_Registryinstance (which was returned from the method) internally on completion -
Execution of
_initCurrency()resumes, starting with thegetResource()call; this returns theZend_Registryinstance stored under that key in the bootstrap. -
Execution of
_initCurrency()completes, and the bootstrap stores the returnedZend_Currencyinstance. -
The
bootstrap()method then attempts to call the_initRegistry()method, but notes that it has already been executed, and thus moves on to execute resource plugins.
As you can see by now, the bootstrap functionality is quite flexible and powerful, and provides a number of benefits immediately out of the box.
Until next time...
At this point, you should have enough to get started writing your own bootstrap initialization resources. In coming weeks, I'll blog about how to build reusable resource plugins, as well as discuss how bootstrapping fits into modular applications.
blog comments powered by Disqus