写php程序时会直接把数据库、缓存的连接信息放在config.php文件里。这样做有两个弊端,1.在开发调试时必须先把连接信息改成本地的,要提交代码时再改回远程的,麻烦,也容易遗漏。2.开发人员可以直接看到线上数据库的连接地址、账号、密码,不安全。
http://leo108.com/pid-2184.asp
线上运行PHP程序时通常需要一个Http服务器,例如apache、nginx。以nginx为例,在配置文件中可以通过fastcgi_param指令来给PHP传递变量 leo108's blog
fastcgi_param DB_HOST "192.168.1.1";
这样就可以在PHP代码里通过$_SERVER[‘DB_HOST’]来获取到对应的值。 PHP
所以开发环境和线上环境只要配好nginx的配置,就可以实现不改代码执行程序了。
配置
更进一步,可以传递一个标示当前环境的变量,例如
PHP
fastcgi_param CODE_ENV "production";
然后在程序里可以根据$_SERVER[‘CODE_ENV’]的不同来执行一些不同的逻辑(比如开发环境会打印所有错误信息而线上环境不显示)
配置
并没有,在实际应用中发现有两个问题:1.如果这个PHP程序不仅仅提供web服务,还提供了cli工具(例如数据库升级脚本),这个时候nginx传递的变量就过不来了。2.貌似不支持传递数组变量。 http://leo108.com/pid-2184.asp
要同时支持web和cli,通过nginx配置传变量已经行不通了,那能不能走php自己的配置呢?
leo108's blog
于是在php.ini的末尾加上如下配置:
http://leo108.com/pid-2184.asp
[userconf]userconf.db_host=127.0.0.1userconf.db_name=test
重启php-fpm之后,发现通过ini_get(‘userconf.db_host’)取到的数据是空,于是详细查看了php的文档,发现对于自定义的配置项,需要通过get_cfg_var()函数来获得。经过测试,在web和cli模式下,通过get_cfg_var(‘userconf.db_host’)可以拿到正确的值。
配置
但这个方案还是有弊端:1.修改配置需要重启php-fpm。2.虽然php.ini里面支持数组的数据,但是还是不够灵活,最好是能直接用php配置。
配置
所以我们可以在php.ini里面只配置一个配置目录的路径,这个目录下放置各个程序的配置文件,php程序先从php.ini获取到这个目录的路径,再从这个目录下读取php格式的配置文件。示例代码: 配置
$path = get_cfg_var('userconf.dir');$conf = include($path . '/test.php');
这样配置文件是每次访问都会重新读取,变更时不需要重启php-fpm;而且不同的站点只要选择不同的配置文件名,就可以在一台服务器上共存。