前言
关于如何读取和配置PHP的$_ENV变量,网上已经有很好的总结,如:PHP增加$_ENV变量
但是,对于在Ubuntu下的配置,会有一些差异。对于初学者,如果不明白其中的区别,很容易会困惑,甚至花费了大量的时间还是没能解决正确读取$_ENV这一问题。这里,简单备忘一下,如何在Ubuntu系统上,对于php5.6,怎样在cli命令行模式和php-fpm模式下读取和配置$_ENV。
本次的环境为:
Ubuntu 16.04.2 LTS
PHP 5.6.30-11+deb.sury.org~xenial+3
php-fpm的配置与读取
1、首先,要开启$_ENV
把/etc/php/5.6/fpm/php.ini配置文件原来的:
variables_order = "GPCS"
改成(在前面追加E,表示$_ENV变量):
variables_order = "EGPCS"
对于重启php-fpm,可以有两种方式,一种是使用service,没有错误提示即表明重启成功。如:
# service php5.6-fpm restart
另一种是直接使用php5.6-fpm的脚本,重启成功后,可以看到相应的提示。如:
# /etc/init.d/php5.6-fpm restart
[ ok ] Restarting php5.6-fpm (via systemctl): php5.6-fpm.service.
2、配置$_ENV变量
接下来,这一步比较关键。很多文章都是说在 php-fpm.conf 文件中添加$_ENV的变量,如在/etc/php/5.6/fpm/php-fpm.conf配置文件中添加:
env[DOGSTAR]=$DOGSTAR
然后,重启php-fpm,结果不但配置没生效,而且连php-fpm都重启失败了。错误提示如下:
# /etc/init.d/php5.6-fpm restart
[....] Restarting php5.6-fpm (via systemctl): php5.6-fpm.serviceJob for php5.6-fpm.service failed because the control process exited with error code. See "systemctl status php5.6-fpm.service" and "journalctl -xe" for details.
failed!
把刚才添加的配置去掉后,就能恢复正常了。
曾经一度,我被困在这个环节,也花了很多时间去解决。最后,经排查,在/etc/php/5.6/fpm/php-fpm.conf配置文件中有这么一行配置,即表示它还引用了pool.d目录下的配置文件。
include=/etc/php/5.6/fpm/pool.d/*.conf
再看一下,会发现pool.d目录下只有一个配置文件,即:/etc/php/5.6/fpm/pool.d/www.conf,打开它,会发现有这样的配置内容:
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
虽然被注释了,但我们找到了配置$_ENV的正确位置!随后,在这后面添加我们需要添加的配置,如直接配置:
env[DOGSTAR]=dogstar
也可以配置系统变量,再通过系统变量去读取,如:
env[DOGSTAR]=dogstar
env[MY_REDIS_HOST]=$MY_REDIS_HOST
系统变量以“$”开头,这时,需要在/etc/profile文件添加相应的变量:
export MY_REDIS_HOST="localhost"
source后,正常情况下能看到刚设置的系统变量。
# source /etc/profile && echo $MY_REDIS_HOST
localhost
添加配置后,为了方便php-fpm在每次重启时自动载入系统变量,可以在/etc/init.d/php5.6-fpm脚本中,加上:
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# 新增一行,自动载入系统配置
. /etc/profile
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
最后,记得要重启一下php-fpm。
3、通过php-fpm读取$_ENV
最后,可以编写一个文件./index.php,放置读取$_ENV的代码,测试一下效果,如:
<?php
var_dump(getenv('DOGSTAR'), $_ENV['DOGSTAR']);
var_dump(getenv('MY_REDIS_HOST'), $_ENV['MY_REDIS_HOST']);
正常情况下,可以看到:
string 'dogstar' (length=7)
string 'dogstar' (length=7)
string '' (length=0)
string '' (length=0)
php-fpm读取不到环境变量?
如果php-fpm读取不到系统环境变量,怎么办?如下图,显示为“no value”。
但运行php-fpm的用户的确已经可以正常读取到环境变量,如:
su -s /bin/bash -c "echo $MY_REDIS_HOST" www-data
localhost
排查清单:
确保配置为:clear_env = no
确保sudo下php有权限读取环境变量
通过fpm配置传递 fpm在每次启动时都会读取php-fpm.conf文件中的环境变量设置,如: env[ENV_XXX]="test test" 或者让fpm读取系统环境变量,如:env[ENV_XXX]=$ENV_XXX 注意此种方式要确保系统环境变量存在,且不被sudo禁用。如果fpm是用sudo方式启动,默认sudo会禁用一些环境变量,可以通过以下方式放开限制:vim /etc/sudoers Defaultsenv_reset Defaultsenv_keep = "ENV_XXX" 或者干脆放开所有限制:Defaults!env_reset
确保 env[PATH] 已开启并添加所需要的值
Summary is: Locate your www.conf file in your php5-fpm config folder (for Ubuntu this is /etc/php5/fpm/pool.d/www.conf) and uncomment the needed env[PATH] line.
Optionally update the content of the variable with the output of php -r "echo getenv('PATH');"
// TODO (这里花费了大量的时间,但仍未得解)
第二部分:cli的配置与读取
1、开启cli模式下的$_ENV
# php --ini
Configuration File (php.ini) Path: /etc/php/5.6/cli
Loaded Configuration File: /etc/php/5.6/cli/php.ini
如果不知道用的是哪个ini配置文件,可以用 php --ini 查看,如上面所示,通常情况下用的都是 /etc/php/5.6/cli/php.ini 配置文件。打开此文件,然后把里面的:
variables_order = "GPCS"
同样,改成(在前面追加E,表示$_ENV变量):
variables_order = "EGPCS"
2、配置cli下的$_ENV
开启了cli下的$_ENV后,那它的配置存放在哪呢?找到有这样的一段话:
My system is Ubuntu and I have set my environment variables in /etc/environment.
If I'm running PHP script using CLI - environment variables from /etc/environment are recognized.
这表明,cli下的$_ENV配置是存在 /etc/environment 里!为了区分与php-fpm的配置,在这个文件里添加:
export MY_REDIS_HOST=$MY_REDIS_HOST
export DOGSTAR="dogstar_from_enviroment"
3、cli下读取$_ENV配置
配置好后,不需要重启php,通过getenv()或者$_ENV即可读取相应的配置。如前面的index.php文件,执行效果如下:
$ php ./index.php
string(23) "dogstar_from_enviroment"
string(23) "dogstar_from_enviroment"
string(9) "localhost"
string(9) "localhost"
如果读取不到,可以先source一下。
$ source /etc/environment
小结
对于php-fpm模式
配置开关variables_order = "EGPCS" 在 /etc/php/5.6/fpm/php.ini 配置文件中设置(如果不知是哪个文件,可通过 ps -ef | grep php,或phpinfo() 查看)
env的配置保存在 /etc/php/5.6/fpm/php-fpm.conf 文件
配置后需要重启php-fpm
对于php cli模式
配置开关 variables_order = "EGPCS" 在 /etc/php/5.6/cli/php.ini 配置文件中设置(如果不知是哪个文件,可以使用 php --ini 查看)
env的配置保存在 /etc/environment 文件
配置后,需要 source /etc/environment,不需要重启php-fpm