<ac:macro ac:name="toc"><ac:parameter ac:name="style">disc</ac:parameter><ac:parameter ac:name="indent">20px</ac:parameter></ac:macro>
<h2>What it should do</h2>
<ul>
<li>Define environments
<ul>
<li>Define common default environments: development, testing, production</li>
<li>Allow for user-specified environments (e.g., staging2, qa, etc)</li>
</ul>
</li>
<li>Provide hooks to common application initialization events/resources
<ul>
<li>Identify common events/resources
<ul>
<li>configuration</li>
<li>route setup</li>
<li>controller/module directory setup</li>
<li>view and layout setup</li>
<li>db initialization</li>
<li>i8n resources</li>
<li>etc</li>
</ul>
</li>
</ul>
</li>
<li>Allow plugin architecture for events/resources
<ul>
<li>Would allow arbitrary resources
<ul>
<li>Resources should be objects</li>
<li>Application class should either be subclassed to add resources, or have methods to add resources</li>
</ul>
</li>
</ul>
</li>
<li>Proxy front controller dispatching <ac:emoticon ac:name="question" />
<ul>
<li>dispatching Application object should dispatch front controller</li>
<li>dispatching should bootstrap if bootstrapping has not occurred</li>
</ul>
</li>
<li>Initialization events/resources should:
<ul>
<li>act as factories for appropriate objects
<ul>
<li>use sensible defaults</li>
<li>allow specifying classes for given initializers</li>
<li>would potentially require rewriting objects to accept configuration arrays in the constructors</li>
</ul>
</li>
<li>allow for injecting objects instead of factory usage</li>
<li>be allowed to run independently</li>
<li>be allowed to run all at once</li>
<li>allow for dependencies
<ul>
<li>i.e., if one initializer depends on another, it should trigger it</li>
</ul>
</li>
<li>Resources should contain a reference to the application object
<ul>
<li>for dependencies and configuration</li>
</ul>
</li>
</ul>
</li>
<li>Be configuration driven
<ul>
<li>Should allow passing configuration or location of configuration file to constructor</li>
</ul>
</li>
<li>Allow for programmatic use
<ul>
<li>Should allow complete initialization programmatically</li>
</ul>
</li>
<li>Initialize the PHP environment (preferably at instantiation, but potentially by calling a method)
<ul>
<li>error_reporting</li>
<li>display_errors</li>
<li>etc. – any INI value, basically</li>
<li>Initialize the include_path, library, and autoloading
<ul>
<li>allow specifying the include_path</li>
<li>Allow specifying alternate autoloading classes</li>
<li>initialize autoloading</li>
</ul>
</li>
</ul>
</li>
<li>Setup and/or invoke module bootstrapping
<ul>
<li>Standard bootstrap location per module</li>
<li>Module bootstrapping should use objects (potentially same or alternate bootstrap interface), and utilize standard, configurable naming convention (such as Module_Bootstrap)</li>
<li>Should occur prior to routing (to allow loading routes and plugins)</li>
</ul>
</li>
</ul>
<h2>Use Cases</h2>
<p><strong>Please note:</strong> the code samples below should not necessarily be indicative of the expected or final API.</p>
<ul>
<li>Obviously, for bootstrapping the front controller</li>
<li>Also, for bootstrapping service scripts
<ul>
<li>Why?
<ul>
<li>Why invoke the whole MVC for services?</li>
<li>Typically, services need faster response times</li>
<li>Services may cache data differently</li>
</ul>
</li>
<li>Example:
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
require_once APPLICATION_PATH . '/Bootstrap.php';
$app = new Bootstrap(APPLICATION_ENV, APPLICATION_PATH . '/config/site.ini');
$app->initDb();
$app->initModules();
$server = new Zend_XmlRpc_Server();
$server->setClass(new Bta_Model_Paste);
echo $server->handle();
]]></ac:plain-text-body></ac:macro></li>
</ul>
</li>
<li>Job scripts
<ul>
<li>Why?
<ul>
<li>Many things are better left to cronjobs: search index generation, mailing, etc.</li>
<li>Cronjobs need the same environment as the application</li>
</ul>
</li>
<li>Example:
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
require_once APPLICATION_PATH . '/Bootstrap.php';
$app = new Bootstrap(APPLICATION_ENV, APPLICATION_PATH . '/config/site.ini');
$app->initLucene();
$config = $app->getConfig();
$spider = new Bta_Search_Spider($config->lucene);
$spider->process();
]]></ac:plain-text-body></ac:macro></li>
</ul>
</li>
<li>Testing
<ul>
<li>Why?
<ul>
<li>No-brainer: you need to test your applications</li>
<li>Testing requires its own environment</li>
</ul>
</li>
<li>Example:
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
require_once APPLICATION_PATH . '/Bootstrap.php';
$app = new Bootstrap('testing', APPLICATION_PATH . '/config/site.ini');
$app->bootstrap();
]]></ac:plain-text-body></ac:macro></li>
</ul>
</li>
</ul>
8 Comments
comments.show.hideDec 02, 2008
Wil Sinclair
<p>I don't want to get in to the implementation details of precisely what interface Zend_Application might expose, but I think requirements along the lines of the following are reasonable: </p>
<ul>
<li>Zend_Application should not expose an API that depends on other Zend Framework components or any other library. IE, the API should reflect the use-at-will nature of the entire framework.</li>
<li>Zend_Application should support all components in the extras library or completely external to the ZF project with a consistent interface/paradigm.</li>
</ul>
Dec 03, 2008
Jordan Ryan Moore
<p>+ logger initialization</p>
Dec 03, 2008
Matthew Weier O'Phinney
<p>Logger initialization would happen as a plugin resource. <ac:emoticon ac:name="smile" /></p>
Dec 05, 2008
Ben Scholzen
<p>Matthew, when this is done, could you port requirements to the actual proposal page?</p>
Dec 05, 2008
Matthew Weier O'Phinney
<p>I plan to. <ac:emoticon ac:name="smile" /></p>
Dec 25, 2008
fc
<p>This is great. We have ZF installed in one of our dev server and we are using it to create a small app. The first thing that caught my attention is the amount of time it took us to setup the application. We are using Hudson and Ant as our build tool, and therefore we need a component like this one to define different environments. We have a dev/testing/integration/staging/prod servers, and we use different directories and files to define environment settings. It takes time to setup this manually, so I think this can help speed up things a bit more. </p>
<p>Also, I don't understand why ZF encourages developers to group all the environment variables in one single file, in this case site.ini. What happens when you build and deploy? You deploy all these settings to all your environments? </p>
Dec 25, 2008
Matthew Weier O'Phinney
<p>Actually, both Zend_Config_Ini and Zend_Config_Xml support inheritence, and by default require that you specify a section or environment to load at instantiation. This means that while all the configuration for all environments is in one location, the actual config object only has the configuration for the selected section. Inheritence of sections means that you can significantly reduce the amount of redundant configuration settings – ensuring that the configurations stay in sync.</p>
Jan 10, 2009
Matthew Ratzloff
<p>Two points to consider:</p>
<p>1. Users should be able to bootstrap arbitrary components so long as they follow a convention of some sort. If I create My_Whatsit, I should be able to initialize it the same as the front controller or any other Zend component, without a lot of extra hassle.</p>
<p>2. At my company, we have a platform and a variety of applications that are built on the platform. the Zend components are configured in the following way: both the platform and the application each have a config.ini with production, staging, and development sections, with staging and development extending production. Based on a environment variable (think RAILS_ENV), both configs are loaded and then merged, with the application config winning.</p>
<p>So for configuration I'd like to be able to pass Zend_Application an array of paths, similar to Zend_View, along with the section to load, and have it merge everything itself.</p>