php项目根据环境读取配置的方案

通常我们会将不同环境的配置使用不同名称的文件区分开来,比如开发环境使用dev.config,线上环境使用prod.conf,来尽可能地减少混淆出错的可能性,但是我们的代码是同一套,这样就会带来一个问题:如何根据当前的部署环境读取合适的配置?针对这个问题,根据一些实战经验,这里谈一下自己总结的三种方案。

方案一:将环境配置文件从版本控制系统中忽略

我们可以在项目中定义一个文件env.php,并在env.php定义具体的环境变量,同时将这个env.php排除在版本控制器之外(使用git的话就使用gitignore配置排除),最后在项目的入口文件中引入这个env.php,这样每个环境就可以自行在env.php中配置。

1
2
3
// env.php文件
<?php
defined('PHP_ENV') or define('PHP_ENV', 'dev');

这个方案很灵活,但带来的一个问题是要管理的env.php可能会很多,因为一台机器上可能同时部署了好几个项目,每个项目都有一个env.php文件需要维护。

方案二:在web服务器中配置环境变量

php可以使用getenv()函数拿到环境变量,使用apache或者nginx可以在配置文件中定义这个环境变量,来看一个nginx配置环境变量的例子:

1
fastcgi_param  PHP_ENV dev;

这个方案不需要在代码中定义环境变量,但还是存在维护多个配置的问题,同时如果是运行控制台的php命令,不通过web服务器,则拿不到对应的环境变量。

方案三:定义linux服务器的环境变量

getenv()函数可以拿到linux配置的环境变量,通常可以在linux的启动文件/etc/profile中加入如下的命令配置:

1
export PHP_ENV='dev'

运行web项目,还需要在配置中加入环境变量的读取,这里以nginx+php-fpm为例,需要在php-fpm.conf增加如下的配置:

1
env[PHP_ENV] = $PHP_ENV //读取linux系统的环境变量

最后将. /etc/profile加入到php的启动脚本中去,就大功告成了。
这个方案应该是上述方案中可维护性最高的,因为配置的地方最少,但是这个方案也存在一个问题:不够灵活,假如我们的服务器资源吃紧,需要在同一台机器上面既部署开发环境的东西,也部署测试环境的东西,这个方案就不能采用。

小结

当然,上述三种方案并非是单选题,也可以组合起来用,例如方案二和方案三,当我们在web服务器和linux机器定义了相同的环境变量,则在web项目中会以web服务器的为基准,这样子组合起来使用,将可以应对更多的使用场景。