zendFramework引导过程通过Application组件完成,由于是对老版本的兼容扩展,其实现起来感觉没有yii那样优雅,它把类库当做资源,而原来那些类库又没有统一的接口,因此又需要新写资源类来间接配置和获取相应的资源。
Zend_Application
zendFramework配置的加载通过入口文件实例Zend_Application来完成,构造方法通过初始化配置后,通过setOptions方法来加载应用的配置。在配置中主要有phpsettings、includepaths、autoloadernamespaces、autoloaderzfpath、bootstrap、appnamespace、resources等。
- public function setOptions(array $options)
- {
- if (!empty($options['config'])) {
- if (is_array($options['config'])) {
- $_options = array();
- foreach ($options['config'] as $tmp) {
- $_options = $this->mergeOptions($_options, $this->_loadConfig($tmp));
- }
- $options = $this->mergeOptions($_options, $options);
- } else {
- $options = $this->mergeOptions($this->_loadConfig($options['config']), $options);
- }
- }
- $this->_options = $options;
- $options = array_change_key_case($options, CASE_LOWER);
- $this->_optionKeys = array_keys($options);
- if (!empty($options['phpsettings'])) {
- $this->setPhpSettings($options['phpsettings']);
- }
- if (!empty($options['includepaths'])) {
- $this->setIncludePaths($options['includepaths']);
- }
- if (!empty($options['autoloadernamespaces'])) {
- $this->setAutoloaderNamespaces($options['autoloadernamespaces']);
- }
- if (!empty($options['autoloaderzfpath'])) {
- $autoloader = $this->getAutoloader();
- if (method_exists($autoloader, 'setZfPath')) {
- $zfPath = $options['autoloaderzfpath'];
- $zfVersion = !empty($options['autoloaderzfversion'])
- ? $options['autoloaderzfversion']
- : 'latest';
- $autoloader->setZfPath($zfPath, $zfVersion);
- }
- }
- if (!empty($options['bootstrap'])) {
- $bootstrap = $options['bootstrap'];
- if (is_string($bootstrap)) {
- $this->setBootstrap($bootstrap);
- } elseif (is_array($bootstrap)) {
- if (empty($bootstrap['path'])) {
- throw new Zend_Application_Exception('No bootstrap path provided');
- }
- $path = $bootstrap['path'];
- $class = null;
- if (!empty($bootstrap['class'])) {
- $class = $bootstrap['class'];
- }
- $this->setBootstrap($path, $class);
- } else {
- throw new Zend_Application_Exception('Invalid bootstrap information provided');
- }
- }
- return $this;
- }
在zf应用中,把框架中类库的看做资源,配置中以resources开头的都是资源相关配置,如resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"配置控制器所在的目录。Zend_Application通过配置实例化Bootstrap来配置资源。
- public function setOptions(array $options)
- {
- $this->_options = $this->mergeOptions($this->_options, $options);
- $options = array_change_key_case($options, CASE_LOWER);
- $this->_optionKeys = array_merge($this->_optionKeys, array_keys($options));
- $methods = get_class_methods($this);
- foreach ($methods as $key => $method) {
- $methods[$key] = strtolower($method);
- }
- if (array_key_exists('pluginpaths', $options)) {
- $pluginLoader = $this->getPluginLoader();
- foreach ($options['pluginpaths'] as $prefix => $path) {
- $pluginLoader->addPrefixPath($prefix, $path);
- }
- unset($options['pluginpaths']);
- }
- foreach ($options as $key => $value) {
- $method = 'set' . strtolower($key);
- if (in_array($method, $methods)) {
- $this->$method($value);
- } elseif ('resources' == $key) {
- foreach ($value as $resource => $resourceOptions) {
- $this->registerPluginResource($resource, $resourceOptions);
- }
- }
- }
- return $this;
- }
- /**
- * 获取内部和外部配置资源并执行
- */
- protected function _bootstrap($resource = null)
- {
- if (null === $resource) {
- //引导类内部方法
- foreach ($this->getClassResourceNames() as $resource) {
- $this->_executeResource($resource);
- }
- //配置中的资源
- foreach ($this->getPluginResourceNames() as $resource) {
- $this->_executeResource($resource);
- }
- } elseif (is_string($resource)) {
- $this->_executeResource($resource);
- } elseif (is_array($resource)) {
- foreach ($resource as $r) {
- $this->_executeResource($r);
- }
- } else {
- throw new Zend_Application_Bootstrap_Exception('Invalid argument passed to ' . __METHOD__);
- }
- }
- /**
- * Execute a resource 执行资源并注册全局资源实例
- */
- protected function _executeResource($resource)
- {
- $resourceName = strtolower($resource);
- if (in_array($resourceName, $this->_run)) {
- return;
- }
- if (isset($this->_started[$resourceName]) && $this->_started[$resourceName]) {
- throw new Zend_Application_Bootstrap_Exception('Circular resource dependency detected');
- }
- $classResources = $this->getClassResources();
- if (array_key_exists($resourceName, $classResources)) {
- $this->_started[$resourceName] = true;
- $method = $classResources[$resourceName];
- $return = $this->$method();
- unset($this->_started[$resourceName]);
- $this->_markRun($resourceName);
- if (null !== $return) {
- $this->getContainer()->{$resourceName} = $return;
- }
- return;
- }
- if ($this->hasPluginResource($resource)) {
- $this->_started[$resourceName] = true;
- $plugin = $this->getPluginResource($resource);
- $return = $plugin->init();
- unset($this->_started[$resourceName]);
- $this->_markRun($resourceName);
- if (null !== $return) {
- $this->getContainer()->{$resourceName} = $return;
- }
- return;
- }
- throw new Zend_Application_Bootstrap_Exception('Resource matching "' . $resource . '" not found');
- }
引导程序加载完成后,通过run()方法,获取前端控制器,然后前端控制器执行对请求的应答过程。