Chapter 6. Standardise The Bootstrap Class With Zend_Application

6.1. Introduction

Up until recently, creating and managing the bootstrapping of a Zend Framework application was strictly a job for the developer's imagination. This encouraged a diverse set of practices from using monolithic procedural scripts to classes of any structure or complexity, not to mention it doubtlessly made designing a command line tool very difficult. With the introduction of Zend_Application, the practice of bootstrapping now has a common base usable in any application by any developer reinforcing a move towards standardisation of this application need. Now if only they had made that obvious called it Zend_Bootstrap...

Zend_Application was designed to be modular, customisable and configurable with a minimum of trouble. To get us underway, since we'll be using Zend_Application throughout the book (a lot!), lets revisit our previous Hello World example, and rearchitect the ZFExt_Bootstrap class. One thing I will not change is the location of our bootstrap which will remain at /library/ZFExt/Bootstrap.php. There's no particular reason why we should keep it here other than the ZFExt namespace will form the basis for our generic application library where we will keep any Zend Framework specific custom classes for potential reuse across other applications in the future.

6.2. Step 1: Editing the ZFExt_Bootstrap Class

The edits needed for our previous bootstrap class start off simple:

  • class ZFExt_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  • {
  • }

We will need to make some changes to reflect what we were achieving with the original ZFExt_Bootstrap class, but if you had no changes your requirements for editing a bootstrap could stop here. Without any additional code, Zend_Application can setup everything needed using each necessary component's defaults.

Here, we're extending Zend_Application_Bootstrap_Bootstrap which extends Zend_Application_Bootstrap_BootstrapAbstract and offers everything needed for a typical bootstrap setup, such as loading Resources, dispatching through the Front Controller, and some checking to ensure we have a proper mode of operation (i.e. production or development) set.

6.3. Step 2: Editing The Index and htaccess Files

As before, our index.php file in /public is where we first include and execute bootstrapping. We need to add a little more complexity here. This includes setting constants to hold some application paths, loading of a configuration to drive the bootstrapping of our environment setup, and running the bootstrapping itself.

  • <?php
  • if (!defined('APPLICATION_PATH')) {
  • define('APPLICATION_PATH',
  • realpath(dirname(__FILE__) . '/../application'));
  • }
  • if (!defined('APPLICATION_ROOT')) {
  • define('APPLICATION_ROOT', realpath(dirname(__FILE__) . '/..'));
  • }
  • if (!defined('APPLICATION_ENV')) {
  • if (getenv('APPLICATION_ENV')) {
  • $env = getenv('APPLICATION_ENV');
  • } else {
  • $env = 'production';
  • }
  • define('APPLICATION_ENV', $env);
  • }
  • set_include_path(
  • APPLICATION_ROOT . '/library' . PATH_SEPARATOR
  • . APPLICATION_ROOT . '/vendor' . PATH_SEPARATOR
  • . get_include_path()
  • );
  • require_once 'Zend/Application.php';
  • $application = new Zend_Application(
  • APPLICATION_ENV,
  • APPLICATION_ROOT . '/config/application.ini'
  • );
  • $application->bootstrap()->run();

Here we discover a continued focus on using index.php as the location for environmental specific setup. In index.php we create a number of constants, setup our include_path and run the bootstrapping process. Internally, Zend_Application loads up our ZFExt_Bootstrap class which we will configure in an application configuration file at /config/application.ini to be executed. Even though our class is empty, it still extends an Abstract class holding all the needed methods.

One thing to note is that these constants need to be treated with some responsibility. Constants are global values accessible from anywhere in the application, and like any global variable their use must be minimised and handled with care because there is always the temptation to use them everywhere. Other applications may not even create these constants, so any code relying on them may not be reusable. A far better solution outside of index.php is to keep on using dirname() and realpath() and/or passing in these variables via a registry object or as Front Controller parameters accessible from your Controller actions.

In a slight departure from the Reference Guide, I maintain index.php according to the Zend Framework Coding Standard. It's preferably not to use shorthand or abbreviated statement forms since they are not very readable.

You will notice that our index.php file now appears to default to a "production" configuration in the absence of an environmental value assigned to the constant APPLICATION_ENV. Obviously, we don't want to develop using a production configuration unless we enjoy debugging applications that mysteriously fail to display their errors, but we can solve this by adding the necessary environmental value to our .htaccess file:

SetEnv APPLICATION_ENV development

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d

RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]

This works for Apache, for other web servers please consult their documentation.

6.4. Step 3: Adding The Application Configuration File

One of the main advantages of using Zend_Application, is that once you remove the need for custom code you can focus your efforts only on setting up component defaults and driving the rest through configuration. As our index.php content above suggests, we should add a configuration file at /config/application.ini which contains:

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
bootstrap.path = APPLICATION_ROOT "/library/ZFExt/Bootstrap.php"
bootstrap.class = "ZFExt_Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

Here, the configuration file is split into four distinct modes: production, staging, testing and development. All modes inherit all values from production, but may set exceptions. For example, production settings disable display_errors while testing and development modes ensure they are enabled. You can be sure that Zend_Application will load the correct mode based on the value we've given it for the APPLICATION_ENV constant set in index.php.

The INI values used may seem a bit strange since they show our PHP constants followed by a space and then a double quoted relative path from the absolute path these constants define. Zend_Application will handle the concatenation of these two parts internally so just be aware that you can setup paths in this manner for the component. In fact you can also setup arrays from INI configuration files also, as we'll see in later chapters.

Zend_Application divides all configurations into a few categories shown on the configuration file as prefixes. "phpSettings" refers to anything you can set using ini_set() from PHP. "includePaths" contains any path you want to add to the PHP include_path value (besides those set from index.php). For example, I could use:

includePaths.foolib = APPLICATION_ROOT "/foolib/lib"

Instead I set the include path from index.php more directly for the standard /library and /vendor directories but you may have others that need to be added. "bootstrap" tells Zend_Application where our Bootstrap class is located, and what its classname is (remember we still need our ZFExt_Bootstrap class to change how bootstrapping sets up some components).

Finally we have "resource" which refers to Zend_Application Resources.

Basically a Zend_Application Resource is any class Zend_Application is aware of and which it will configure for use during bootstrapping. Above we set options for a FrontController (the option name lowercases the first letter) to configure the instance of Zend_Controller_Front that Zend_Application will utilise when running our application. For now, we're only telling Zend_Controller_Front where to find our default directory containing Controller classes, and whether it should throw Exceptions when in the development or testing modes. If the configuration convention is confusing, "controllerDirectory" maps to Zend_Controller_Front::setControllerDirectory(). Just as if we were using an array of configuration values, using the same convention to map array keys to the setter methods that each key corresponds to.

6.5. Step 4: Handling Setting Of Standard Component Defaults

In our original ZFExt_Bootstrap class, I made a point that some components are configured by default in a way we may find unsuitable for use. For example, Zend_View uses a default character encoding of ISO-8859-1 which is great, so long as you avoid accented or multibyte characters. You can customise the default Zend_View instance just as we did originally using Zend_Application, and in much the same way too!

  • <?php
  • class ZFExt_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  • {
  • protected function _initView()
  • {
  • $view = new Zend_View();
  • $view->setEncoding('UTF-8');
  • $view->doctype('XHTML1_STRICT');
  • $view->headMeta()->appendHttpEquiv(
  • 'Content-Type', 'text/html;charset=utf-8'
  • );
  • $viewRenderer =
  • Zend_Controller_Action_HelperBroker::getStaticHelper(
  • 'ViewRenderer'
  • );
  • $viewRenderer->setView($view);
  • return $view;
  • }
  • }

Here we see that our revised Bootstrap class can configure a Zend_View instance by calling _initView(), something referred to a Resource Method, since it sets up or modifies a Resource for use. Here we are setting up a new Zend_View instance for use by the ViewRenderer Action Helper (we'll meet Action Helpers later) where it acts as the application's default Zend_View instance for rendering templates. All Resource Methods to be run must follow the format "_initResourceName()" if a protected method. You can do the same using public methods by defining such methods in the form "bootstrapResourceName()". Whether you use protected or public methods is your decision.

Inside these Resource Methods we can do a bit more by using Zend_Application's Resource system. Basically, Zend_Application defines a number of classes called Resource Plugins which it uses to setup Resources as an alternative to these simple Resource Methods.

So, what is a Resource after all this? Resource is something of a confusing term since it doesn't tell the entire story. The best way to think about it is in terms of configuring unique objects. Our application generally only requires one of each object when bootstrapping. It needs one instance of Zend_View, one instance of Zend_Controller_Front, one instance of a Router, etc. So a Resource is unique - one of a kind. The set of actions needed to create, configure and register these unique resources with Zend_Application (and the bootstrap class) come in two distinct alternative forms: Resource Methods, and Resource Plugins. Both of these follow a convention whereby the Resource they apply to is used in the method name for a Resource Method or the classname for a Resource Plugin. So, _initView() creates a Resource called View. But wait, there's also a Resource Plugin (Zend_Application_Resource_View) which may also create a Resource called View. Can we have two View Resources? The answer is no - we can have one and one only. By defining a Resource Method, we effectively override any Resource Plugin applicable to the same Resource.

A Resource Plugin is any class which extends Zend_Application_Resource_ResourceAbstract (or Zend_Application_Resource_Resource) which carries out the actual initialisation, configuration and passing of such classes as objects to the Front Controller. A Resource Method is like a Resource Plugin, but it's defined in the bootstrap class instead of extracted into its own separate class. To create new objects for use during bootstrapping, you may therefore add custom Resource Plugin classes for this purpose or Resource Methods as a short alternative.

Of course, Zend_Application will automatically handle some standard classes your application may require without interference. The Resource Plugins pre-packaged with Zend_Application include:

Zend_Application_Resource_Db
Zend_Application_Resource_FrontController
Zend_Application_Resource_Router
Zend_Application_Resource_Modules
Zend_Application_Resource_Navigation
Zend_Application_Resource_Session
Zend_Application_Resource_View
Zend_Application_Resource_Layout
Zend_Application_Resource_Locale
Zend_Application_Resource_Translate
[Note] Note

Several of these are omitted from the Reference Guide as of Zend Framework 1.9.0. Only those absolutely necessary lead to initialised Resources, so Zend_Application_Resource_Db will not immediately go and complain about a missing configuration setting because it's not run by default until you configure it.

In our _initView() method we were creating a replacement or substitute Zend_View object, because Zend_Application_Resource_View will just create a default instance with the ISO-8859-1 character encoding and other default options. By returning the new Zend_View instance from _initView(), Zend_Application will accept the replacement and will not attempt to overwrite our changes by running Zend_Application_Resource_View to set up a standard default Zend_View instance with the flaws we just corrected.

When creating a new Resource to replace another one, we don't need to retrieve the original one setup by the default Resource Plugin in Zend_Application unless it's needed. Let's now add another resource method, _initFrontController(), which only changes some settings on an existing resource as setup by Zend_Application_Resource_Frontcontroller.

  • <?php
  • class ZFExt_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  • {
  • protected function _initView()
  • {
  • $view = new Zend_View();
  • $view->setEncoding('UTF-8');
  • $view->doctype('XHTML1_STRICT');
  • $view->headMeta()->appendHttpEquiv(
  • 'Content-Type', 'text/html;charset=utf-8'
  • );
  • $viewRenderer =
  • Zend_Controller_Action_HelperBroker::getStaticHelper(
  • 'ViewRenderer'
  • );
  • $viewRenderer->setView($view);
  • return $view;
  • }
  • protected function _initFrontController()
  • {
  • $this->bootstrap('FrontController');
  • $front = $this->getResource('FrontController');
  • $response = new Zend_Controller_Response_Http;
  • $response->setHeader('Content-Type',
  • 'text/html; charset=UTF-8', true);
  • $front->setResponse($response);
  • }
  • }

In our original bootstrap class, we wanted to ensure all responses defaulted to using a Content-Type header value of "text/html; charset=UTF-8". Here, we do the same thing by using the getResource() method to retrieve an instance of Zend_Controller_Front created and configured by Zend_Application_Resource_Frontcontroller and merely ensure it uses our own Response object instead of creating a default one when needed. Before retrieving the FrontController Resource, i.e. an object of type Zend_Controller_Front, we first need to make sure Zend_Application does everything needed to create it in the first place.

This is done by passing the Resource Name (i.e. the final term in it's corresponding Resource Plugin class name) to the bootstrap() method. This forces Zend_Application to bootstrap just this Resource. The bootstrap() method is pretty flexible and accepts an array of Resource Names you need to have available right now without waiting for an overall bootstrap execution.

You can take this a step further by simply replacing the default Resource Plugins. I won't cover it here since we'll be covering adding custom Resource Plugins for other objects used in our application later in the book.

For now compare the original ZFExt_Bootstrap class with its revised version. Less code, configuration driven, easy to work with, and extendable via Resource Plugins. The new version is an obvious improvement. Of course, understanding how it works is yet another hurdle on the way to becoming a Zend Framework guru, but that's always the cost when using more abstract classes which are nevertheless more extendable and reusable than their monolithic alternatives.

6.6. Step 5: Fixing ZFExt_Bootstrap

If you just try accessing http://helloworld.tld once more, you will notice something odd. There is now a rather anonymous Exception being thrown stating "Circular resource dependency detected". This occurs because we defined a resource method _initFrontController() which conflicts with Zend_Application_Resource_Frontcontroller when calling bootstrap('FrontController'). Effectively we broke the rule about Resources being unique - by attempting to use the Resource Method and forcing the use of the Resource Plugin (which bootstrap() runs) Zend_Application interpreted this as an attempt to create two similar objects when we only needed one. Until we get used to thinking about bootstrap work in terms of unique Resources, this will be a common mistake.

This is really to emphasis the importance of Resource Methods vs Resource Plugins (as well as to explain this anonymous little gem when starting with Zend_Application). You can use one or the other, but never both with the same Resource Name at the same time. Our previous _initView() method worked because there is no reference to Zend_Application_Resource_View used - our Resource Method replaces it. If we had been trying to merely change the object generated by Zend_Application_Resource_View using the bootstrap() and getResource() methods to generate and retrieve the object, we would have had to rename the Resource Method to reflect that we were building on the Plugin initialised Resource by creating a modified version of it (effectively a different Resource even if the difference was mere configuration).

This illustrates an important point - even though Zend_Application speaks about Resources, you can have a single object represented by two or more named Resources. It seems a bit silly, since at the end of the day just that one object is used regardless of how many Resource names apparently refer to it. This is really a simple contrivance though - in order to modify objects after their initial setup from Plugins or Methods (not recommended - method order is tricky), we must use a different Resource name when doing so. It doesn't need to make sense, it's just the way it works.

In _initFrontController(), we made the mistake of believing we could modify an existing Front Controller by retrieving it from Zend_Application_Resource_FrontController, without realising we were doing this in a Resource Method using the same resource name. The moment one Resource unit tries to use another similar named Resource unit, confusion reigns since we cannot have two objects representing the same Resource, so Zend_Application throws an Exception complaining about the dependency mess we tried creating. This is a deliberate safety net.

To solve this conflict, we should rename any Resource Methods not intended to replace a Resource Plugin to something a bit more unique. In this case I've decided to prefix the existing Resource Name "FrontController" with "Modified" indicating that our Resource Method does not override a Resource Plugin, i.e. we may use the results of that Resource Plugin when it runs rather than do our own separate creation work. We also do not return the object since the Resource Plugin will register the original object for use anyway.

  • <?php
  • class ZFExt_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  • {
  • protected function _initView()
  • {
  • $view = new Zend_View();
  • $view->setEncoding('UTF-8');
  • $view->doctype('XHTML1_STRICT');
  • $view->headMeta()->appendHttpEquiv(
  • 'Content-Type', 'text/html;charset=utf-8'
  • );
  • $viewRenderer =
  • Zend_Controller_Action_HelperBroker::getStaticHelper(
  • 'ViewRenderer'
  • );
  • $viewRenderer->setView($view);
  • return $view;
  • }
  • protected function _initModifiedFrontController()
  • {
  • $this->bootstrap('FrontController');
  • $front = $this->getResource('FrontController');
  • $response = new Zend_Controller_Response_Http;
  • $response->setHeader('Content-Type',
  • 'text/html; charset=UTF-8', true);
  • $front->setResponse($response);
  • }
  • }

Now we can try http://helloworld.tld once more without meeting any errors or exceptions.

6.7. Step 6: Integrating Application Configuration Into Resource Methods

In our application configuration file, application.ini, we noted that we can define a configuration for Resources using the "resources" prefix. These are automatically used by the Zend_Application Resource Plugins to pass options into the objects they create. So for our FrontController Resource, we can add entries like:

resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

Here the Resource name is camel cased with the first letter in lower case, so FrontController becomes frontController. This is not an immediate worry but we can clean up our replacement Zend_View Resource Method a little by ensuring any configuration options added to application.ini are passed to the new instance. If nothing else, it also lets us push the setting of a character encoding back into the configuration file.

  • <?php
  • class ZFExt_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  • {
  • public static function autoload($class) {
  • include str_replace('_', '/', $class) . '.php';
  • return $class;
  • }
  • protected function _initView()
  • {
  • $options = $this->getOptions();
  • if (isset($options['resources']['view'])) {
  • $view = new Zend_View($options['resources']['view']);
  • } else {
  • $view = new Zend_View;
  • }
  • if (isset($options['resources']['view']['doctype'])) {
  • $view->doctype($options['resources']['view']['doctype']);
  • }
  • if (isset($options['resources']['view']['contentType'])) {
  • $view->headMeta()->appendHttpEquiv('Content-Type',
  • $options['resources']['view']['contentType']);
  • }
  • $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
  • 'ViewRenderer'
  • );
  • $viewRenderer->setView($view);
  • return $view;
  • }
  • protected function _initModifiedFrontController()
  • {
  • $options = $this->getOptions();
  • if (!isset($options['resources']['modifiedFrontController']['contentType'])) {
  • return;
  • }
  • $this->bootstrap('FrontController');
  • $front = $this->getResource('FrontController');
  • $response = new Zend_Controller_Response_Http;
  • $response->setHeader('Content-Type',
  • $options['resources']['modifiedFrontController']['contentType'], true);
  • $front->setResponse($response);
  • }
  • }

Now we can delegate setting the character encoding and any custom configuration options that we require to our application.ini settings.

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
bootstrap.path = APPLICATION_ROOT "/library/ZFExt/Bootstrap.php"
bootstrap.class = "ZFExt_Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.view.encoding = "UTF-8"
resources.view.doctype = "XHTML1_STRICT"
resources.view.contentType = "text/html;charset=utf-8"
resources.modifiedFrontController.contentType = "text/html;charset=utf-8"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

6.8. Step 7: Optimising Autoloading Code

In our previous bootstrap class, we created a custom autoload method for use which did no file checking and simply attempted an include() operation assuming all classnames mapped to their filenames using the PEAR Convention. This was to avoid a method Zend_Loader::loadClass() from the more typical autoloader used in Zend Framework applications which does a lot of mostly unnecessary error checking. Zend_Application is designed to also implement autoloading using another new component, Zend_Loader_Autoloader. Unfortunately, Zend_Loader_Autoloader (which adds vastly improved class autoloading features) uses the same Zend_Loader::loadClass() method we wished to avoid.

We can still implement our lighter method, but not from within the bootstrap class anymore. Rather we need to reset the Zend_Loader_Autoloader's default loading method before Zend_Application is initialised, and this can only be accomplished from index.php.

  • <?php
  • if (!defined('APPLICATION_PATH')) {
  • define('APPLICATION_PATH',
  • realpath(dirname(__FILE__) . '/../application'));
  • }
  • if (!defined('APPLICATION_ROOT')) {
  • define('APPLICATION_ROOT', realpath(dirname(__FILE__) . '/..'));
  • }
  • if (!defined('APPLICATION_ENV')) {
  • if (getenv('APPLICATION_ENV')) {
  • $env = getenv('APPLICATION_ENV');
  • } else {
  • $env = 'production';
  • }
  • define('APPLICATION_ENV', $env);
  • }
  • set_include_path(
  • APPLICATION_ROOT . '/library' . PATH_SEPARATOR
  • . APPLICATION_ROOT . '/vendor' . PATH_SEPARATOR
  • . get_include_path()
  • );
  • require_once 'Zend/Loader/Autoloader.php';
  • $autoloader = Zend_Loader_Autoloader::getInstance();
  • $autoloader->setDefaultAutoloader(create_function('$class',
  • "include str_replace('_', '/', \$class) . '.php';"
  • ));
  • $application = new Zend_Application(
  • APPLICATION_ENV,
  • APPLICATION_ROOT . '/config/application.ini'
  • );
  • $application->bootstrap()->run();

Since we can't even reference the bootstrap before Zend_Application is initialised, we may instead pass setDefaultAutoloader() an anonymous function we create on the spot.

6.9. Allowing Zend_Loader_Autoload Load Namespaced Classes

In PHP, where libraries are following the PEAR convention, all class names carry a common prefix commonly referred to as the "namespace" (this is not true namespacing as PHP 5.3 introduces). Our autoloader is configured to recognise class name namespaces including "Zend_" and "ZendX_". In order to load other namespaced classes, we first need to tell the autoloader that they exist. Before that we can ask the question why is this even required in the first place?

The problem with the original autoloading method was simple. It would load anything. At a glance this seems really great, it's simple, easy to understand and requires no configuration. So how is this not a good thing? The problem with the load anything behaviour is that it affords no control. Sometimes you want to make sure only certain libraries can be loaded. As an added benefit, the restriction also leads to faster lookups.

The new namespacing feature isn't perfect but that's mostly because some libraries do not have a top level namespace prefix. For example, PEAR components do not begin with PEAR_ so you can have HTTP_Client, Crypt_RSA, etc. which share no common prefix. A similar problem exists with any "root" classes, for example HTMLPurifier uses the namespace prefix HTMLPurifer_ except for a root class in HTMLPurifier.php. In these circumstances, you may need to return to the original behaviour where namespaces are untracked and unrestricted using:

  • Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true);

In other circumstances, a library may use its own autoloader which you can register as an alternative to the default one implemented by Zend_Loader_Autoloader.

  • $autoloader = Zend_Loader_Autoloader::getInstance();
  • $autoloader->pushAutoloader('HTMLPurifier_Bootstrap', 'autoload');

Note that this, because of HTMLPurifier's lack of a namespace, adds a new global autoloader a bit like the fallback option makes the default autoloader operate globally without any restriction. You can pass in a namespace restricted autoloader in a similar fashion so it's only called when a specific class namespace is detected.

  • $autoloader = Zend_Loader_Autoloader::getInstance();
  • $autoloader->pushAutoloader('XLib_Autoloader', 'autoload', 'XLib_');

However, let's assume for now this fallback and other autloaders are not needed. The outcome of the new autoloader is that we need to register all class namespaces we intend using. While we can do this in code from index.php, it's easier to track it in our application.ini file which makes it easy to add namespaces as needed. Here's an example where we intend using a library (our future application library actually) where all its class members are prefixed with "ZFExt_". As you can probably see, you can keep adding namespaces this way as the square brackets [], indicate they are added to an array once the INI file is parsed by Zend_Config (which handles all configuration parsing and loading within the framework.

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
bootstrap.path = APPLICATION_ROOT "/library/ZFExt/Bootstrap.php"
bootstrap.class = "ZFExt_Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.view.encoding = "UTF-8"
resources.view.doctype = "XHTML1_STRICT"
resources.view.contentType = "text/html;charset=utf-8"
resources.modifiedFrontController.contentType = "text/html;charset=utf-8"
autoloaderNamespaces[] = "ZFExt_"

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.throwExceptions = 1

6.10. Conclusion

This was a quick introduction (well, you could always learn to speed read) to Zend_Application. As someone who has been doing my own thing quietly I'm very happy to adopt it for use. It ensures other developers can follow my bootstrapping process without learning a whole new approach (from the hundreds probably existing in the wild). This is the strength of finally having a standard approach to bootstrapping applications.

We will see more of Zend_Application as the book progresses since there are lots of objects and other pieces of altered behaviour we may require in our applications, and the bootstrap is where initialising these for use is the best approach. On a final note, Zend_Tool which is not covered by the book yet, uses Zend_Application when managing applications.

Powered by jQuery Powered by Zend Framework Powered by Nginx Http Server