【zendframework】引导程序

zendFramework引导过程通过Application组件完成,由于是对老版本的兼容扩展,其实现起来感觉没有yii那样优雅,它把类库当做资源,而原来那些类库又没有统一的接口,因此又需要新写资源类来间接配置和获取相应的资源。


Zend_Application

zendFramework配置的加载通过入口文件实例Zend_Application来完成,构造方法通过初始化配置后,通过setOptions方法来加载应用的配置。在配置中主要有phpsettings、includepaths、autoloadernamespaces、autoloaderzfpath、bootstrap、appnamespace、resources等。

[php]  view plain copy
  1. public function setOptions(array $options)  
  2. {  
  3.     if (!empty($options['config'])) {  
  4.         if (is_array($options['config'])) {  
  5.             $_options = array();  
  6.             foreach ($options['config'as $tmp) {  
  7.                 $_options = $this->mergeOptions($_options$this->_loadConfig($tmp));  
  8.             }  
  9.             $options = $this->mergeOptions($_options$options);  
  10.         } else {  
  11.             $options = $this->mergeOptions($this->_loadConfig($options['config']), $options);  
  12.         }  
  13.     }  
  14.   
  15.     $this->_options = $options;  
  16.   
  17.     $options = array_change_key_case($options, CASE_LOWER);  
  18.     $this->_optionKeys = array_keys($options);  
  19.     if (!empty($options['phpsettings'])) {  
  20.         $this->setPhpSettings($options['phpsettings']);  
  21.     }  
  22.   
  23.     if (!empty($options['includepaths'])) {  
  24.         $this->setIncludePaths($options['includepaths']);  
  25.     }  
  26.   
  27.     if (!empty($options['autoloadernamespaces'])) {  
  28.         $this->setAutoloaderNamespaces($options['autoloadernamespaces']);  
  29.     }  
  30.   
  31.     if (!empty($options['autoloaderzfpath'])) {  
  32.         $autoloader = $this->getAutoloader();  
  33.         if (method_exists($autoloader'setZfPath')) {  
  34.             $zfPath    = $options['autoloaderzfpath'];  
  35.             $zfVersion = !empty($options['autoloaderzfversion'])  
  36.                         ? $options['autoloaderzfversion']  
  37.                         : 'latest';  
  38.             $autoloader->setZfPath($zfPath$zfVersion);  
  39.         }  
  40.     }  
  41.   
  42.     if (!empty($options['bootstrap'])) {  
  43.         $bootstrap = $options['bootstrap'];  
  44.   
  45.         if (is_string($bootstrap)) {  
  46.             $this->setBootstrap($bootstrap);  
  47.         } elseif (is_array($bootstrap)) {  
  48.             if (empty($bootstrap['path'])) {  
  49.                 throw new Zend_Application_Exception('No bootstrap path provided');  
  50.             }  
  51.   
  52.             $path  = $bootstrap['path'];  
  53.             $class = null;  
  54.   
  55.             if (!empty($bootstrap['class'])) {  
  56.                 $class = $bootstrap['class'];  
  57.             }  
  58.             $this->setBootstrap($path$class);  
  59.         } else {  
  60.             throw new Zend_Application_Exception('Invalid bootstrap information provided');  
  61.         }  
  62.     }  
  63.   
  64.     return $this;  
  65. }  
Bootstrap

在zf应用中,把框架中类库的看做资源,配置中以resources开头的都是资源相关配置,如resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"配置控制器所在的目录。Zend_Application通过配置实例化Bootstrap来配置资源。

[php]  view plain copy
  1. public function setOptions(array $options)  
  2. {  
  3.     $this->_options = $this->mergeOptions($this->_options, $options);  
  4.   
  5.     $options = array_change_key_case($options, CASE_LOWER);  
  6.     $this->_optionKeys = array_merge($this->_optionKeys, array_keys($options));  
  7.   
  8.     $methods = get_class_methods($this);  
  9.   
  10.     foreach ($methods as $key => $method) {  
  11.         $methods[$key] = strtolower($method);  
  12.     }  
  13.   
  14.     if (array_key_exists('pluginpaths'$options)) {  
  15.         $pluginLoader = $this->getPluginLoader();  
  16.   
  17.         foreach ($options['pluginpaths'as $prefix => $path) {  
  18.             $pluginLoader->addPrefixPath($prefix$path);  
  19.         }  
  20.         unset($options['pluginpaths']);  
  21.     }  
  22.   
  23.     foreach ($options as $key => $value) {  
  24.   
  25.         $method = 'set' . strtolower($key);  
  26.   
  27.         if (in_array($method$methods)) {  
  28.             $this->$method($value);  
  29.         } elseif ('resources' == $key) {  
  30.             foreach ($value as $resource => $resourceOptions) {  
  31.                 $this->registerPluginResource($resource$resourceOptions);  
  32.             }  
  33.         }  
  34.     }  
  35.     return $this;  
  36. }  
配置加载好后,需要启动支持程序运行的,在_bootstrap()首先通过中getClassResourceNames()将获捕获导类中以_init开头的方法,这些方法是通过在引导类内部配置相关资源,然后获取配置中的资源并执行引导,在执行引导的时候会把资源注册在一个全局容器中,通过getResource($resource)方法可以获取容器中的资源。
[php]  view plain copy
  1. /** 
  2.   * 获取内部和外部配置资源并执行 
  3.   */  
  4. protected function _bootstrap($resource = null)  
  5. {  
  6.   
  7.     if (null === $resource) {  
  8.         //引导类内部方法  
  9.         foreach ($this->getClassResourceNames() as $resource) {  
  10.             $this->_executeResource($resource);  
  11.         }  
  12.         //配置中的资源  
  13.         foreach ($this->getPluginResourceNames() as $resource) {  
  14.             $this->_executeResource($resource);  
  15.         }  
  16.   
  17.     } elseif (is_string($resource)) {  
  18.         $this->_executeResource($resource);  
  19.     } elseif (is_array($resource)) {  
  20.         foreach ($resource as $r) {  
  21.             $this->_executeResource($r);  
  22.         }  
  23.     } else {  
  24.         throw new Zend_Application_Bootstrap_Exception('Invalid argument passed to ' . __METHOD__);  
  25.     }  
  26. }  
  27. /** 
  28.   * Execute a resource 执行资源并注册全局资源实例 
  29.   */  
  30. protected function _executeResource($resource)  
  31. {  
  32.     $resourceName = strtolower($resource);  
  33.     if (in_array($resourceName$this->_run)) {  
  34.         return;  
  35.     }  
  36.   
  37.     if (isset($this->_started[$resourceName]) && $this->_started[$resourceName]) {  
  38.         throw new Zend_Application_Bootstrap_Exception('Circular resource dependency detected');  
  39.     }  
  40.   
  41.     $classResources = $this->getClassResources();  
  42.   
  43.     if (array_key_exists($resourceName$classResources)) {  
  44.         $this->_started[$resourceName] = true;  
  45.         $method = $classResources[$resourceName];  
  46.         $return = $this->$method();  
  47.         unset($this->_started[$resourceName]);  
  48.         $this->_markRun($resourceName);  
  49.   
  50.         if (null !== $return) {  
  51.             $this->getContainer()->{$resourceName} = $return;  
  52.         }  
  53.   
  54.         return;  
  55.     }  
  56.   
  57.     if ($this->hasPluginResource($resource)) {  
  58.         $this->_started[$resourceName] = true;  
  59.         $plugin = $this->getPluginResource($resource);   
  60.   
  61.         $return = $plugin->init();  
  62.         unset($this->_started[$resourceName]);  
  63.         $this->_markRun($resourceName);  
  64.   
  65.         if (null !== $return) {  
  66.             $this->getContainer()->{$resourceName} = $return;  
  67.         }  
  68.   
  69.         return;  
  70.     }  
  71.   
  72.     throw new Zend_Application_Bootstrap_Exception('Resource matching "' . $resource . '" not found');  
  73. }  

引导程序加载完成后,通过run()方法,获取前端控制器,然后前端控制器执行对请求的应答过程。

你可能感兴趣的:(【zendframework】引导程序)