Zend Application

Getting an MVC applicationconfigured and ready to dispatch has required an increasing amountof 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 reuse the same code tobootstrap your tests, a cronjob, or a service script. While it'spossible to simply include your bootstrap script, oftentimes thereare initializations that are environment specific – you may notneed the MVC for a cronjob, orjust the DB layer for a service script.

Zend_Application aims to make thiseasier and to promote reuse by encapsulating bootstrappinginto OOP paradigms.

Zend_Application is broken intothree realms:

  • Zend_Application: loads the PHP environment,including include_paths and autoloading, and instantiates therequested bootstrap class.

  • Zend_Application_Bootstrap: provides interfaces forbootstrap classes.Zend_Application_Bootstrap_Bootstrap providescommon functionality for most bootstrapping needs, includingdependency checking algorithms and the ability to load bootstrapresources on demand.

  • Zend_Application_Resource provides aninterface for standard bootstrapping resources that can be loadedon demand by a bootstrap instance, as well as several defaultresource implementations.

Developers create a bootstrap class for their application,extendingZend_Application_Bootstrap_Bootstrap orimplementing (minimally)Zend_Application_Bootstrap_Bootstrapper.The entry point (e.g., public/index.php) will loadZend_Application,and instantiate it by passing:

  • The current environment

  • Options for bootstrapping

The bootstrap options include the path to the file containing thebootstrap class and optionally:

  • Any extra include_paths to set

  • Any additional autoloader namespaces to register

  • Any php.ini settings toinitialize

  • The class name for the bootstrap class (if not "Bootstrap")

  • Resource prefix to path pairs to use

  • Any resources to use (by class name or short name)

  • Additional path to a configuration file to load

  • Additional configuration options

Options may be an array, a Zend_Config object,or the path to a configuration file.

Bootstrapping 

Zend_Application's second area of responsibility isexecuting the application bootstrap. Bootstraps minimally need toimplement Zend_Application_Bootstrap_Bootstrapper,which defines the following API:

  1. interface  Zend_Application_Bootstrap_Bootstrapper
  2. {
  3.       public   function  __construct ( $application );
  4.       public   function  setOptions ( array   $options );
  5.       public   function  getApplication ( );
  6.       public   function  getEnvironment ( );
  7.       public   function  getClassResources ( );
  8.       public   function  getClassResourceNames ( );
  9.       public   function  bootstrap ( $resource  =   null );
  10.       public   function  run ( );
  11. }

This API allows thebootstrap to accept the environment and configuration from theapplication object, report the resources its responsible forbootstrapping, and then bootstrap and run the application.

You can implement this interface on your own, extendZend_Application_Bootstrap_BootstrapAbstract,or useZend_Application_Bootstrap_Bootstrap.

Besides this functionality, there are a number of other areas ofconcern you should familiarize yourself with.

Resource Methods 

The Zend_Application_Bootstrap_BootstrapAbstract implementationprovides a simple convention for defining class resource methods.Any protected method beginning with a name prefixedwith _init willbe considered a resource method.

To bootstrap a single resource method, use the bootstrap() method,and pass it the name of the resource. The name will be the methodname minus the _init prefix.

To bootstrap several resource methods, pass an array of names. Toobootstrap all resource methods, pass nothing.

Take the following bootstrap class:

  1. class  Bootstrap   extends  Zend_Application_Bootstrap_Bootstrap
  2. {
  3.     protected   function  _initFoo ( )
  4.       {
  5.           //...
  6.       }
  7.  
  8.     protected   function  _initBar ( )
  9.       {
  10.           //...
  11.       }
  12.  
  13.     protected   function  _initBaz ( )
  14.       {
  15.           //...
  16.       }
  17. }

To bootstrap just the _initFoo() method,do the following:

  1. $bootstrap-> bootstrap ( 'foo' );

To bootstrap the _initFoo() and _initBar() methods,do the following:

  1. $bootstrap-> bootstrap ( array ( 'foo',   'bar' ) );

To bootstrap all resource methods, call bootstrap() withno arguments:

  1. $bootstrap-> bootstrap ( );

Bootstraps that use resource plugins 

To make your bootstraps more re-usable, we have provided theability to push your resources into resource plugin classes. Thisallows you to mix and match resources simply via configuration. Wewill cover howto create resources later; in thissection we will show you how to utilize them only.

If your bootstrap should be capable of using resource plugins, youwill need to implement an additional interface, Zend_Application_Bootstrap_ResourceBootstrapper.This interface defines an APIfor locating, registering, and loadingresource plugins:

  1. interface  Zend_Application_Bootstrap_ResourceBootstrapper
  2. {
  3.       public   function  registerPluginResource ( $resource,   $options  =   null );
  4.       public   function  unregisterPluginResource ( $resource );
  5.       public   function  hasPluginResource ( $resource );
  6.       public   function  getPluginResource ( $resource );
  7.       public   function  getPluginResources ( );
  8.       public   function  getPluginResourceNames ( );
  9.       public   function  setPluginLoader (Zend_Loader_PluginLoader_Interface $loader );
  10.       public   function  getPluginLoader ( );
  11. }

Resource plugins basically provide the ability to create resourceintializers that can be re-used between applications. This allowsyou to keep your actual bootstrap relatively clean, and tointroduce new resources without needing to touch your bootstrapitself.

Zend_Application_Bootstrap_BootstrapAbstract (andZend_Application_Bootstrap_Bootstrap byextension) implement this interface as well, allowing you toutilize resource plugins.

To utilize resource plugins, you must specify them in the optionspassed to the application object and/or bootstrap. These optionsmay come from a configuration file, or be passed in manually.Options will be of key to options pairs, with the key representingthe resource name. The resource name will be the segment followingthe class prefix. For example, the resources shipped with ZendFramework have the class prefix "Zend_Application_Resource_";anything following this would be the name of the resource. As anexample,

  1. $application  =   new  Zend_Application (APPLICATION_ENV,   array (
  2.       'resources'  =>   array (
  3.           'FrontController'  =>   array (
  4.               'controllerDirectory'  =>APPLICATION_PATH .   '/controllers',
  5.           ),
  6.       ),
  7. ) );

This indicates that the "FrontController" resource should be used,with the options specified.

If you begin writing your own resource plugins, or utilizethird-party resource plugins, you will need to tell your bootstrapwhere to look for them. Internally, the bootstraputilizesZend_Loader_PluginLoader,so you will only need to indicate the common class prefix an pathpairs.

As an example, let's assume you have custom resource pluginsin APPLICATION_PATH/resources/and that they share thecommon class prefix of My_Resource.You would then pass that information to the application object asfollows:

  1. $application  =   new  Zend_Application (APPLICATION_ENV,   array (
  2.       'pluginPaths'  =>   array (
  3.           'My_Resource'  =>APPLICATION_PATH .   '/resources/',
  4.       ),
  5.       'resources'  =>   array (
  6.           'FrontController'  =>   array (
  7.               'controllerDirectory'  =>APPLICATION_PATH .   '/controllers',
  8.           ),
  9.       ),
  10. ) );

You would now be able to use resources from that directory.

Just like resource methods, you use the bootstrap() methodto execute resource plugins. Just like with resource methods, youcan specify either a single resource plugin, multiple plugins (viaan array), or all plugins. Additionally, you can mix and match toexecute resource methods as well.

  1. //Execute one:
  2. $bootstrap-> bootstrap ( 'FrontController' );
  3.  
  4. //Execute several:
  5. $bootstrap-> bootstrap ( array ( 'FrontController',   'Foo' ) );
  6.  
  7. //Execute all resource methods and plugins:
  8. $bootstrap-> bootstrap ( );

Resource Registry 

Many, if not all, of your resource methods or plugins willinitialize objects, and in many cases, these objects will be neededelsewhere in your application. How can you access them?

Zend_Application_Bootstrap_BootstrapAbstract provides a localregistry for these objects. To store your objects in them, yousimply return them from your resources.

For maximum flexibility, this registry is referred to as a"container" internally; its only requirements are that it is anobject. Resources are then registered as properties named after theresource name. By default, an instance of Zend_Registry isused, but you may also specify any other object you wish. Themethods setContainer() and getContainer() maybe used to manipulate the container itself.getResource($resource) canbe used to fetch a given resource from the container,andhasResource($resource) tocheck if the resource has actually been registered.

As an example, consider a basic view resource:

  1. class  Bootstrap   extends  Zend_Application_Bootstrap_Bootstrap
  2. {
  3.     protected   function  _initView ( )
  4.       {
  5.           $view  =   new  Zend_View ( );
  6.           // moreinitialization...
  7.  
  8.           return   $view;
  9.       }
  10. }

You can then check for it and/or fetch it as follows:

  1. //Using the has/getResource() pair:
  2. if   ( $bootstrap-> hasResource ( 'view' ) )   {
  3.       $view  =   $bootstrap-> getResource ( 'view' );
  4. }
  5.  
  6. // Viathe container:
  7. $container  =   $bootstrap-> getContainer ( );
  8. if   ( isset ( $container-> view ) )   {
  9.       $view  =   $container-> view;
  10. }

Please note that the registry and also the container is not global.This means that you need access to the bootstrap in order to fetchresources. Zend_Application_Bootstrap_Bootstrap providessome convenience for this: during its run() execution,it registers itself as the front controller parameter "bootstrap",which allows you to fetch it from the router, dispatcher, plugins,and action controllers.

As an example, if you wanted access to the view resource from abovewithin your action controller, you could do the following:

  1. class  FooController   extends  Zend_Controller_Action
  2. {
  3.       public   function  init ( )
  4.       {
  5.           $bootstrap  =   $this-> getInvokeArg ( 'bootstrap' );
  6.           $view  =   $bootstrap-> getResource ( 'view' );
  7.           //...
  8.       }
  9. }

Dependency Tracking 

In addition to executing resource methods and plugins, it'snecessary to ensure that these are executed once and once only;these are meant to bootstrap an application, and executing multipletimes can lead to resource overhead.

At the same time, some resources may depend on other resourcesbeing executed. To solve these two issues, Zend_Application_Bootstrap_BootstrapAbstract providesa simple, effective mechanism for dependency tracking.

As noted previously, all resources -- whether methods or plugins --are bootstrapped by callingbootstrap($resource),where $resource isthe name of a resource, an array of resources, or, left empty,indicates all resources should be run.

If a resource depends on another resource, it shouldcall bootstrap() withinits code to ensure that resource has been executed. Subsequentcalls to it will then be ignored.

In a resource method, such a call would look like this:

  1. class  Bootstrap   extends  Zend_Application_Bootstrap_Bootstrap
  2. {
  3.     protected   function  _initRequest ( )
  4.       {
  5.           // Ensure thefront controller is initialized
  6.           $this-> bootstrap ( 'FrontController' );
  7.  
  8.           // Retrieve thefront controller from the bootstrap registry
  9.           $front  =   $this-> getResource ( 'FrontController' );
  10.  
  11.           $request  =   new  Zend_Controller_Request_Http ( );
  12.           $request-> setBaseUrl ( '/foo' );
  13.           $front-> setRequest ( $request );
  14.  
  15.           // Ensure therequest is stored in the bootstrap registry
  16.           return   $request;
  17.       }
  18. }

Resource Plugins 

As noted previously, a good way to create re-usable bootstrapresources and to offload much of your coding to discrete classes isto utilize resource plugins. While Zend Framework ships with anumber of standard resource plugins, the intention is thatdevelopers should write their own to encapsulate their owninitialization needs.

Resource plugins need only implement Zend_Application_Resource_Resource,or, more simply still, extend Zend_Application_Resource_ResourceAbstract.The basic interface is simply this:

  1. interface  Zend_Application_Resource_Resource
  2. {
  3.       public   function  __construct ( $options  =   null );
  4.       public   function  setBootstrap (
  5.         Zend_Application_Bootstrap_Bootstrapper   $bootstrap
  6.       );
  7.       public   function  getBootstrap ( );
  8.       public   function  setOptions ( array   $options );
  9.       public   function  getOptions ( );
  10.       public   function  init ( );
  11. }

The interface defines simply that a resource plugin should acceptoptions to the constructor, have mechanisms for setting andretrieving options, have mechanisms for setting and retrieving thebootstrap object, and an initialization method.

As an example, let's assume you have a common view intializationyou use in your applications. You have a commondoctype, CSS andJavaScript, and you want to be able to pass in a base documenttitle via configuration. Such a resource plugin might look likethis:

  1. class  My_Resource_View   extendsZend_Application_Resource_ResourceAbstract
  2. {
  3.     protected   $_view;
  4.  
  5.       public   function  init ( )
  6.       {
  7.           // Return view sobootstrap will store it in the registry
  8.           return   $this-> getView ( );
  9.       }
  10.  
  11.       public   function  getView ( )
  12.       {
  13.           if   ( null  ===   $this->_view )   {
  14.               $options  =   $this-> getOptions ( );
  15.               $title    =   '';
  16.               if   ( array_key_exists ( 'title',   $options ) )   {
  17.                   $title  =   $options [ 'title' ];
  18.                   unset ( $options [ 'title' ] );
  19.               }
  20.  
  21.               $view  =   new  Zend_View ( $options );
  22.               $view-> doctype ( 'XHTML1_STRICT' );
  23.               $view-> headTitle ( $title );
  24.               $view-> headLink ( )-> appendStylesheet ( '/css/site.css' );
  25.               $view-> headScript ( )-> appendfile ( '/js/analytics.js' );
  26.  
  27.               $viewRenderer  =
  28.                 Zend_Controller_Action_HelperBroker:: getStaticHelper (
  29.                       'ViewRenderer'
  30.                   );
  31.               $viewRenderer-> setView ( $view );
  32.  
  33.               $this->_view=   $view;
  34.           }
  35.           return   $this->_view;
  36.       }
  37. }

As long as you register the prefix path for this resource plugin,you can then use it in your application. Even better, because ituses the plugin loader, you are effectively overriding the shipped"View" resource plugin, ensuring that your own is used instead.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值