Friday, January 8. 2010Quick Start to Zend_Application_BootstrapWe 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.
Additionally, How it worksNow that you know what it does, let's jump into the basics.
If you use the application/ |-- Bootstrap.php | `-- configs/ | | `-- application.ini
The [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
Configuration SettingsWhat we see in the above listing is a set of:
The
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[] = "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 bootstrap.class = "Application_Bootstrap" bootstrap.path = APPLICATION_PATH "/modules/application/Bootstrap.php" Getting started with Bootstrap ResourcesNow 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:
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
Each has its own configuration options, documented in the manual. Writing Resource MethodsWriting 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 $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
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:
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.
Posted by Matthew Weier O'Phinney
in PHP
at
12:57
| Comments (25)
| Trackback (1)
Defined tags for this entry: php, zend framework
Comments
Display comments as
(Linear | Threaded)
Good one
Thanks for telling us in advance the application resources of 1.10. Are there any preferred methods of setting which environment (devel, staging, productoon) will be used for Zend_Application_Bootstrap? I realize there are many ways it could be done but was wondering if you have any thoughts to share?
One method that has worked out reasonably well for me lately is to have a preBootstrap.php that gets included from index.php. In preBootstrap I look at where I'm running ($_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']) and then set APPLICATION_ENV in a big switch. I've even wound up having to set the Zend Framework path when I've had environments which force it to be in different places. The trade-offs for me is that I like to be able to use rsync for releases and not have to change any files (including symlinks) in the source tree between environments. Thanks, --Rob Rob T,
I like use environment variables set in the Vhost declaration of my httpd.conf. Regards, Rob.. Rob:
Yes that's good if you have access to httpd.conf. You wouldn't necessarily have that in a shared hosting environment. I did see your recent post blog about running ZF in a shared hosting environment http://akrabat.com/zend-framework/zend-framework-on-a-shared-host/ (To me running in some sort of shared environment is usually the most common case, especially given cookie restrictions) Thanks, --Rob T. In a shared environment, I would use htaccess to redirect all possibly domain addresses to a single canonical one and then use that as the APPLICATION_ENV using a putenv('APPLICATION_ENV='.$httpHostName); in index.php.
Regards, Rob... As Rob Allen notes, I like to use server environment variables -- and the approach is actually used in the index.php/.htaccess generated by Zend_Tool already.
This allows you to default to production, but have your vhosts in staging and development set a different environment, without requiring you to make any code modifications. Unfortunately this approach does not work with command line scripts. How do you set the environment when running from the command line?
I have solved it by checking if a given file exists and if the file exists it will be included. In the included file I do something like this: define('APPLICATION_ENV', 'staging'); I am curious how other developers have solved this problem? environment variables work just fine for command line:
echo "export SL_ENV=dev" >> ~/.bashrc # SL_ENV being the environment variable we use to detect, well, environment bin/devel/some_script # will use dev environment oh, forgot to mention you would need to source .bashrc (. ~/.bashrc) before running scripts (this won't be necessary once you log out and then log in back).
To change the environment from the command line:
One time run: APPLICATION_ENV=staging php script.php Set for the current session: export APPLICATION_ENV=staging php script.php To set permanently see Bruce Weirdan's comments. That said, I do use your method of using an environment file on hosts that don't allow me to set environment variables via .htaccess Will the $bootstrap variable always be available to Controllers Actions? If not, what's the best way to get an instance of it?
In your controller you can use:
$bootstrap = $this->getInvokeArg('Bootstrap'); Which is the best way to get the Bootstrap object and it's resources within other classes than controllers, e.g. Forms, ViewHelpers etc?
Would it be acceptable to have a class Bootstrap... { ... public function _initBootstrap() {Zend_Registry::set('bootstrap', $this);} } Jakob:
$frontController = Zend_Controller_Front::getInstance(); $view = $frontController->getParam('bootstrap')->getResource('db'); Regards, Rob... »In coming weeks, I'll blog about how to build reusable resource plugins, as well as discuss how bootstrapping fits into modular applications.«
I am eager to learn about module bootstrapping. I am also curious how these things will work in zf 2.0, since standalone modules are not really envisioned within zf 1.x A concern for me is that the Bootstrapping class tends to promote alot of pre-initialization (I'm aware that it can be restricted to certain ini method calls if needed) as opposed to loading on demand. For example db initialization. So at present for me bootstrapping is a minimal effort in initializing the application environment with a 'context' class that extends the Zend_Application class from which all other primary components can be retrieved (on demand) e.g. db, session and access to a Zend_Config object.
So, a few comments.
First, Zend_Db actually is inexpensive to load. The actual database connection does not happen until an operation is made that actually needs to talk to the database. As such, you shouldn't be worried about it. As for your approach, it's one that's not unfamiliar to me. A number of ZF users are using DI containers such as Yadif or the new Symfony DI container in conjunction with Zend_Application; this allows them to populate the container with the appropriate configuration, and then retrieve objects on demand from it later. Some do this by replacing the "container" within the bootstrap object with their DI container -- an operation that is not only fully supported, but part of the design. The idea with any form of bootstrapping is that you initialize only what is needed for every request, and also that you provide enough configuration information that anything else may be loaded on-demand later. As such, your approach makes complete sense -- and is not incompatible with the architecture of Zend_Application as it currently stands. This is great, but I dont need entire navigation or ACL on every page, i don't need logger as well on every request. Is there a way to lazy load resources, or sth like that? to instantiate them on demand, when I need them, dynamically.
I'll be covering that in another post. The short answer: there are ways to allow it in the existing infrastructure: you can initialize controller plugins per-bootstrap that only initialize information if the module is matched in the request, or, as binarykitten blogged recently, do some additional logic from a single front controller plugin that calls additional initialization from the matched module.
Nice article. I think, it will very useful to beginners.
You not against if I publish translation of this article in the my blog? My translate of this article to russian language - http://lobach.info/develop/zf/quick-start-to-zend_application_bootstrap/
Add Comment
|
CalendarQuicksearchLinks
ArchivesCategoriesSyndicate This BlogShow tagged entries |






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.
Tracked: Jan 09, 00:34