在 Zend Framework 1.* 中,可以根据 Apache 服务器的环境配置来让程序调用不同的设置。
主要用于在不同情况下,调用不同的数据库、不同的警告和错误级别等:例如,在开发环境下调用本机数据库和最低级别的警告和错误提示,在测试环境下调用测试数据库和最低级别的警告和错误提示,在发布环境中调用正式数据库和较高级别的警告和错误提示。
在 ZF 1 中,可以在 Apache 的 SetEnv 指令,配合 ZF 1 的 APPLICATION_ENV 常量,以及项目目录中的 /configs/application.ini 来实现这一目的。
Apache 示例:

1 1 <VirtualHost *:80> 2 2 DocumentRoot "E:/ZF1/public" 3 3 ServerName .local 4 4 5 5 # This should be omitted in the production environment 6 6 SetEnv APPLICATION_ENV development 7 7 8 8 <Directory "E:/ZF1/public"> 9 9 Options Indexes MultiViews FollowSymLinks 10 10 AllowOverride All 11 11 Order allow,deny 12 12 Allow from all 13 13 </Directory> 14 14 15 15 </VirtualHost>
/public/index.php 入口文件示例:

1 <?php 2 3 // Define path to application directory 4 defined('APPLICATION_PATH') 5 || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 6 7 // Define application environment 8 defined('APPLICATION_ENV') 9 || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); 10 11 // Ensure library/ is on include_path 12 set_include_path(implode(PATH_SEPARATOR, array( 13 realpath(APPLICATION_PATH . '/../library'), 14 get_include_path(), 15 ))); 16 17 /** Zend_Application */ 18 require_once 'Zend/Application.php'; 19 20 // Create application, bootstrap, and run 21 $application = new Zend_Application( 22 APPLICATION_ENV, 23 APPLICATION_PATH . '/configs/application.ini' 24 ); 25 $application->bootstrap() 26 ->run();
/configs/application.ini 配置文件示例:

1 [production] 2 phpSettings.display_startup_errors = 0 3 phpSettings.display_errors = 0 4 includePaths.library = APPLICATION_PATH "/../library" 5 bootstrap.path = APPLICATION_PATH "/Bootstrap.php" 6 bootstrap.class = "Bootstrap" 7 appnamespace = "Application" 8 resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" 9 resources.frontController.params.displayExceptions = 0 10 11 [staging : production] 12 13 [testing : production] 14 phpSettings.display_startup_errors = 1 15 phpSettings.display_errors = 1 16 17 [development : production] 18 phpSettings.display_startup_errors = 1 19 phpSettings.display_errors = 1 20 resources.frontController.params.displayExceptions = 1
在 ZF 2 中,没有提供这一方法,只提供了用本地配置文件替换全局配置文件的方法,即在 /config/autoload 文件夹中可以放置 *global.php 文件,并在其中放置全局配置数组,再放置 *local.php 配置文件,在其中放置本地配置数组。
在载入时,会自动用 local 配置覆盖 global 配置,同时利用 svn 和 git 等版本控制工具,将 *local.php 排除在提交文件之外,以保证本地配置文件不会影响到生产环境和其他人。
但是这种方法有局限性,一是利用了 svn 和 git 的特性,二是只有两级配置。
以下提供一种类似于 ZF 1 的解决方案,思路是根据 Apache 中 SetEnv 指令设置的 APPLICATION_ENV 变量来设置 PHP 的 APPLICATION_ENV 常量,再根据此常量值来载入不同的配置文件。
Apache 示例:

1 Listen 6001 2 NameVirtualHost *:6001 3 4 <Directory "E:/clbx.cn/public"> 5 AllowOverride All 6 Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec 7 <Limit GET POST OPTIONS> 8 Order allow,deny 9 Allow from all 10 </Limit> 11 <LimitExcept GET POST OPTIONS> 12 Order deny,allow 13 Deny from all 14 </LimitExcept> 15 </Directory> 16 17 <VirtualHost *:6001> 18 SetEnv APPLICATION_ENV development 19 ServerAdmin admin@huigu.com 20 DocumentRoot "E:/clbx.cn/public" 21 ServerName local.zlbx.cn 22 ErrorLog "logs/local.zlbx.cn-error.log" 23 CustomLog "logs/local.zlbx.cn-access.log" common 24 </VirtualHost> 25 26 Listen 6002 27 NameVirtualHost *:6002 28 29 <VirtualHost *:6002> 30 SetEnv APPLICATION_ENV local 31 ServerAdmin admin@huigu.com 32 DocumentRoot "E:/clbx.cn/public" 33 ServerName local.zlbx.cn 34 ErrorLog "logs/local.zlbx.cn-error.log" 35 CustomLog "logs/local.zlbx.cn-access.log" common 36 </VirtualHost> 37 38 Listen 6003 39 NameVirtualHost *:6003 40 41 <VirtualHost *:6003> 42 SetEnv APPLICATION_ENV test 43 ServerAdmin admin@huigu.com 44 DocumentRoot "E:/clbx.cn/public" 45 ServerName local.zlbx.cn 46 ErrorLog "logs/local.zlbx.cn-error.log" 47 CustomLog "logs/local.zlbx.cn-access.log" common 48 </VirtualHost> 49 50 Listen 6004 51 NameVirtualHost *:6004 52 53 <VirtualHost *:6004> 54 SetEnv APPLICATION_ENV production 55 ServerAdmin admin@huigu.com 56 DocumentRoot "E:/clbx.cn/public" 57 ServerName local.zlbx.cn 58 ErrorLog "logs/local.zlbx.cn-error.log" 59 CustomLog "logs/local.zlbx.cn-access.log" common 60 </VirtualHost>
注意其中带有 SetEnv APPLICATION_ENV 指令的那些行。这样在带有不同端口时,就会产生不同的 APPLICATION_ENV 变量值。
项目 /public/index.php 入口文件:

1 <?php 2 /** 3 * This makes our life easier when dealing with paths. Everything is relative 4 * to the application root now. 5 */ 6 chdir(dirname(__DIR__)); 7 8 // Define application environment 9 defined('APPLICATION_ENV') 10 || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development')); 11 12 // Setup autoloading 13 require 'init_autoloader.php'; 14 15 // Run the application! 16 Zend\Mvc\Application::init(require 'config/application.config.php')->run();
注意,下面这三行是原文件没有的:

1 // Define application environment 2 defined('APPLICATION_ENV') 3 || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
修改 /module/Application/Module.php:

1 <?php 2 return array( 3 'modules' => array( 4 'Application', 5 ), 6 7 'module_listener_options' => array( 8 'module_paths' => array( 9 './module', 10 './vendor', 11 ), 12 13 'config_glob_paths' => array( 14 'config/autoload/{,*.}' . APPLICATION_ENV . '.{global,local}.php', //原为 'config/autoload/{,*.}{global,local}.php', 15 ), 16 17 ), 18 );
注意第 14 行。
在浏览器中访问 localhost:6001、localhost:6002、localhost:6003、localhost:6004 就会调用不同的配置。
此方案的缺点是不能像 ZF 1 那样,配置之间可以有继承关系,虽然通过修改 /module/Application/Module.php,可以部分实现,总是不够灵活,期待 Zend 官方提供更好的解决方案。
在项目 /config/autoload 文件夹分别建立 development.local.php、test.local.php、test.global.php、production.global.php 文件,分别针对 开发环境、本地测试环境、服务器测试环境、产品环境,内容分别如下:
development.local.php:

1 <?php 2 /** 3 * Global Configuration Override 4 * 5 * You can use this file for overriding configuration values from modules, etc. 6 * You would place values in here that are agnostic to the environment and not 7 * sensitive to security. 8 * 9 * @NOTE: In practice, this file will typically be INCLUDED in your source 10 * control, so do not include passwords or other sensitive information in this 11 * file. 12 */ 13 14 return array( 15 /** 16 * 设置 php 环境。 17 */ 18 'phpSettings' => array( 19 'display_startup_errors' => true, 20 'display_errors' => true, 21 'max_execution_time' => 60, 22 'date.timezone' => 'Asia/Shanghai', 23 'mbstring.internal_encoding' => 'UTF-8', 24 ), 25 'db' => array( 26 'driver' => 'Pdo', 27 'dsn' => 'mysql:dbname=development;host=localhost', 28 'driver_options' => array( 29 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 30 ), 31 ), 32 'service_manager' => array( 33 'factories' => array( 34 'Zend\Db\Adapter\Adapter' 35 => 'Zend\Db\Adapter\AdapterServiceFactory', 36 ), 37 ), 38 );
test.local.php:

1 <?php 2 /** 3 * Global Configuration Override 4 * 5 * You can use this file for overriding configuration values from modules, etc. 6 * You would place values in here that are agnostic to the environment and not 7 * sensitive to security. 8 * 9 * @NOTE: In practice, this file will typically be INCLUDED in your source 10 * control, so do not include passwords or other sensitive information in this 11 * file. 12 */ 13 14 return array( 15 /** 16 * 设置 php 环境。 17 */ 18 'phpSettings' => array( 19 'display_startup_errors' => true, 20 'display_errors' => true, 21 'max_execution_time' => 60, 22 'date.timezone' => 'Asia/Shanghai', 23 'mbstring.internal_encoding' => 'UTF-8', 24 ), 25 'db' => array( 26 'driver' => 'Pdo', 27 'dsn' => 'mysql:dbname=testlocal;host=localhost', 28 'driver_options' => array( 29 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 30 ), 31 ), 32 'service_manager' => array( 33 'factories' => array( 34 'Zend\Db\Adapter\Adapter' 35 => 'Zend\Db\Adapter\AdapterServiceFactory', 36 ), 37 ), 38 );
test.global.php:

1 <?php 2 /** 3 * Global Configuration Override 4 * 5 * You can use this file for overriding configuration values from modules, etc. 6 * You would place values in here that are agnostic to the environment and not 7 * sensitive to security. 8 * 9 * @NOTE: In practice, this file will typically be INCLUDED in your source 10 * control, so do not include passwords or other sensitive information in this 11 * file. 12 */ 13 14 return array( 15 /** 16 * 设置 php 环境。 17 */ 18 'phpSettings' => array( 19 'display_startup_errors' => true, 20 'display_errors' => true, 21 'max_execution_time' => 60, 22 'date.timezone' => 'Asia/Shanghai', 23 'mbstring.internal_encoding' => 'UTF-8', 24 ), 25 'db' => array( 26 'driver' => 'Pdo', 27 'dsn' => 'mysql:dbname=testglobal;host=localhost', 28 'driver_options' => array( 29 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 30 ), 31 ), 32 'service_manager' => array( 33 'factories' => array( 34 'Zend\Db\Adapter\Adapter' 35 => 'Zend\Db\Adapter\AdapterServiceFactory', 36 ), 37 ), 38 );
production.global.php:

1 <?php 2 /** 3 * Global Configuration Override 4 * 5 * You can use this file for overriding configuration values from modules, etc. 6 * You would place values in here that are agnostic to the environment and not 7 * sensitive to security. 8 * 9 * @NOTE: In practice, this file will typically be INCLUDED in your source 10 * control, so do not include passwords or other sensitive information in this 11 * file. 12 */ 13 14 return array( 15 /** 16 * 设置 php 环境。 17 */ 18 'phpSettings' => array( 19 'display_startup_errors' => true, 20 'display_errors' => true, 21 'max_execution_time' => 60, 22 'date.timezone' => 'Asia/Shanghai', 23 'mbstring.internal_encoding' => 'UTF-8', 24 ), 25 'db' => array( 26 'driver' => 'Pdo', 27 'dsn' => 'mysql:dbname=production;host=localhost', 28 'driver_options' => array( 29 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 30 ), 31 ), 32 'service_manager' => array( 33 'factories' => array( 34 'Zend\Db\Adapter\Adapter' 35 => 'Zend\Db\Adapter\AdapterServiceFactory', 36 ), 37 ), 38 );