Added by Ben Scholzen, last edited by Matthew Weier O'Phinney on Dec 15, 2008  (view change) show comment

Labels

 
(None)

Zend Framework: Zend_Application Component Proposal

Proposed Component Name Zend_Application
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Application
Proposers Ben Scholzen
Zend Liaison Matthew Weier O'Phinney
Revision 1.0 - 16 September 2008: Initial Draft.
1.1 - 30 September 2008: Renamed to Zend_Application.
1.1 - 30 November 2008: Continued work (wiki revision: 13)

Table of Contents

1. Overview

Zend_Application is a component to simplify and normalise the entire bootstrapping procedure into an easy and extensible system. This proposal uses ideas from other proposals like Zend_Application, which was archived yet. It is intended to take care of the entire ZF enviroment setup like database, view, layout and controller.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component MUST be configuration driven. Configuration may take the form of any combination of the following
    • MUST allow programmatic configuration (i.e., via method calls)
    • MUST allow passing configuration to the constructor via an array, Zend_Config object, or path to configuration file
    • SHOULD allow passing configuration to one or more mutators via an array, Zend_Config object, or path to configuration file
  • This component MUST provide bootstrapping of the PHP environment (i.e., any ini_set-configurable keys)
    • This component MUST allow setting the application include_path (aka library)
    • This component MUST allow autoload initialization
      • It SHOULD allow specifying the alternate autoloading classes
    • PHP environment bootstrapping MUST occur at instantiation, prior to application bootstrapping
  • This component MUST allow specification of environments
    • Common default environments MUST be supported (development, testing, production)
  • This component MUST provide a plugin architecture for common application events/resources
    • This component MUST provide common resources
      • configuration
      • route setup
      • controller/module directory setup
      • view and layout setup
      • DB initialization
      • cache initialization
      • i18n setup
      • etc
    • This component MUST allow specification and utilization of arbitrary resources
    • Resources SHOULD
      • run independently
      • run in groups or all at once
      • allow for dependencies
      • use naming conventions for initialization
  • This component MUST account for initialization of independent modules
    • It SHOULD allow configuration of a standard bootstrap script location per module
    • Module bootstrapping MUST run independently
    • Module bootstrapping MUST be triggered by the application bootstrap

4. Dependencies on Other Framework Components

  • Zend_Exception
  • Zend_Loader
  • Zend_Loader_Autoload (TBA)
  • Zend_Loader_Autoload_Resource (TBA)
  • Zend_Loader_PluginLoader

5. Theory of Operation

Getting an MVC application configured and ready to dispatch has required an increasing amount of code as more features become available: setting up the database, configuring your view and view helpers, configuring your layouts, registering plugins, registering action helpers, and more.

Additionally, you will often want to re-use the same code to bootstrap your tests, a cronjob, or a service script. While it's possible to simply include your bootstrap script, oftentimes there are initializations that are environment specific – you may not need the MVC for a cronjob, or just the DB layer for a service script.

Zend_Application aims to make this easier and to promote reuse by encapsulating bootstrapping into OOP paradigms.

Zend_Application is broken into three realms:

  • Zend_Application: loads the PHP environment, including include_paths and autoloading, and instantiates the requested bootstrap class
  • Zend_Application_Bootstrap: provides an interface for bootstrap classes. Zend_Application_Bootstrap_Base provides common functionality for most bootstrapping needs, including dependency checking algorithms and the ability to load bootstrap resources on demand.
  • Zend_Application_Bootstrap_Resource provides an interface for standard bootstrapping resources that can be loaded on demand by a bootstrap instance.

Developers will create a bootstrap class for their application, extending Zend_Application_Bootstrap_Base or implementing Zend_Application_Bootstrap. The entry point (e.g., public/index.php) will load Zend_Application, and instantiate it by passing:

  • The current environment
  • Options for bootstrapping

Bootstrap options will include:

  • Optionally, any extra include_paths to set
  • Optionally, any additional autoloader namespaces to register
  • Optionally, any php.ini settings to initialize
  • Path to the file containing the bootstrap class
  • Optionally, the class name for the bootstrap class (if not "Bootstrap")
  • Optionally, resource prefix/path pairs to use
  • Optionally, any resources to use (by class name or short name)
  • Optionally, additional configuration options

To simplify setup, a path to a configuration file may be provided.

The Bootstrap class itself will typically be fairly minimal; often, it could consist of solely the following:

However, should custom initialization be necessary, the developer has two choices. First, they can write methods prefixed with "_init" to specify discrete code to bootstrap. These methods will be called by bootstrap(), and can also be called as if they were public methods: init<resource>(). They should accept an optional array of options.

Note in this example the call to "initFrontController"; this ensures that the front controller has been initialized prior to calling this method. That call may trigger either a resource or another method in the class.

The other option is to use bootstrap resources. Bootstrap resources are objects that perform specific initializations, and may be specified:

  • when instantiating the Zend_Application object
  • during initialization of the bootstrap object
  • by explicitly enabling them via method calls to the bootstrap object

Resources implement Zend_Application_Bootstrap_Resource, which defines simply that they allow injection of the caller and options, and that they have an init() method. As an example, a custom "View" bootstrap resource might look like the following:

To tell the bootstrap to use this, you would need to provide either the class name of the resource, or a combination of a plugin loader prefix path and the short name of the resource (e.g, "view"):

Resources can call on other resources and initializers by accessing the parent object:

In normal usage, you would instantiate the application, bootstrap it, and run it:

For a custom script, you might need to simply initialize specific resources:

6. Milestones / Tasks

  • Milestone 1: Requirement specifications
  • Milestone 2: Creating working prototype
  • Milestone 3: Unit tests exist
  • Milestone 4: Documentation exists

7. Class Index

  • Zend_Application
  • Zend_Application_Exception
  • Zend_Application_Bootstrap
  • Zend_Application_Bootstrap_Base
  • Zend_Application_Bootstrap_Module
  • Zend_Application_Bootstrap_Resource
  • Zend_Application_Bootstrap_Resource_Base
  • Zend_Application_Bootstrap_Resource_Exception
  • Zend_Application_Bootstrap_Resource_Db
  • Zend_Application_Bootstrap_Resource_Front
  • Zend_Application_Bootstrap_Resource_Layout
  • Zend_Application_Bootstrap_Resource_Session
  • Zend_Application_Bootstrap_Resource_View

8. Use Cases

9. Class Skeletons

Introduction and how it relates to Zym_App

First of all, this component is really needed. ZF lacks a standardized way of bootstrapping the application, and a component like this would both make it easier for newcomers to get into the bootstrapping process as well as allowing devs to move on to application specific coding right away. Combined with Zend_Tool, this component should hopefully allow newcomers to make the basic "Hello World!" MVC app in 5 minutes.

The proposal references Bill Karwin's Zend_Application from a while back. That proposal is currently refined and implemented as Zym_App, so a lot of functionality could be taken from that implementation. It has been revised in several iterations (found a couple of quirks and gotchas), and is currently in a fully functional and stable state.

Zym_App related links:

Now, time for thoughts and feedback.

 What should the component do?

Mainly, the component should follow convention over configuration, and it should be possible to dispatch/run the bootstrap with decent configuration with a single line of code in index.php or bootstrap.php. Convention in bootstrapping means that by default, the component should use the default project structure (currently a proposal), and it should follow best practices regarding how other components are used and set up. Then, following the ZF spirit of use-at-will (and may I add use-however-you-like), the component should be flexible enough allow developers to set up virtually anything related to bootstrapping through configuration settings.

Bootstrapping becomes a somewhat heavy process which would have to be done for each request. This is leveraged by lazy loading and caching. Lazy loading is indeed supported inherently in most ZF classes, but caching is something users have to set up themselves. The bootstrap class should be self-cachable with no effort at all.

Resources / bootstrap modules

The way flexibility is added to Zym_App/Zend_Application is by letting the bootstrap class load arbitrary application resources. Resources are best described as "bootstrap modules", which is a means of providing moduarized bootstrapping. Example resources are; 1) Controller, 2) Cache, 3) View, and 4) Db, which would respectively set up; 1) classes in the Zend_Controller package (like Zend_Controller_Front), 2) classes related to caching, 3) Zend_View package (or any other view implementation you'd like), including helper paths, view helpers, etc, and 4) database connection(s) and Zend_Db setup.

Resources, or boostrap modules, have a predefined default configuration (this is where best practice should be followed), and allows users to override any of the settings by using config files. The responsibilities of "what resources should be loaded" and "which configuration file(s) should be loaded" are delegated to the bootstrap class, which reads a user defined configuration file, possibly also with a user defined "runtime environment" like development/testing/production, and dispatches the resources defined in the configuration file for the given environment. Each resource has its own responsibility, which makes it easy to see where and how the application is set up and dispatched.

The environment is a rather important aspect of the bootstrap process, because it allows different application setups for development, staging, production, testing, CLI, and so on. Say you want to disable caching when developing, but want full-blown page caching in production. Or for testing you might want to use a mock database in sqlite. Or you want a CLI interface to your application, in which case you don't want to use Zend_Controller_Front and Zend_View at all. Using different settings for different environments makes all of this trivial, and you don't lose control of where things are set up.

Relation to other components

The proposal for Zend_Container looks interesting, and could probably be used in Zend_Bootstrap/Zym_App. Also, the resource dispatching process could use some event handling features to allow arbitrary callbacks for certain events in the process. This should be implemented using Zend_Message. Currently, Zym_App does not utilize Zend_Loader_PluginLoader to load classes, but the bootstrap class should aggregate a plugin loader and allow user defined paths and prefixes to be added (for resources).

Conclusion (for now)

Bootstrapping deals with setting up arbitrary application resources. The component should be flexible enough to set up anything, and simple enough to bootstrap an application with a single line. Default configurations should follow best practices.

That's it for now, but I will follow this proposal with genuine interest and care.

Please take a look here: Myak class. I wrote this class and you can use some ideas from it (if you want ).
Can i help you with this proposal?

Posted by Hinikato Dubrai at Dec 24, 2008 23:16 Updated by Hinikato Dubrai