前言
关于如何读取和配置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 ,参考:Environment variables and PHP
2、通过fpm配置传递 fpm在每次启动时都会读取PHP-fpm.conf文件中的环境变量设置,如: env[ENV_XXX]="test test" 或者让fpm读取系统环境变量,如: env[ENV_XXX]=$ENV_XXX 注意此种方式要确保系统环境变量存在,且不被sudo禁用。 如果fpm是用sudo方式启动,默认sudo会禁用一些环境变量,可以通过以下方式放开限制: vim /etc/sudoers Defaults env_reset Defaults env_keep = "ENV_XXX" 或者干脆放开所有限制: Defaults !env_reset
- 确保 env[PATH] 已开启并添加所需要的值,参考:No environment variables are available via PHP-fpm+nginx
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后,那它的配置存放在哪呢?之前没留意看stackoverflow上的英文内容,走了不少弯路。如在:
How to get system environment variables into PHP while running CLI & Apache2Handler?
上面有这样的一段话:
My system isUbuntuand I have set my environment variables in
/etc/environment
.If I'm runningPHPscript usingCLI- 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模式,