文档章节

【完整手记】Ubuntu+PHP5.6+cli+php-fpm下如何读取和配置$_ENV

暗夜在火星
 暗夜在火星
发布于 2017/05/31 17:21
字数 1598
阅读 331
收藏 0

前言

关于如何读取和配置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

 

排查清单:

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

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 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

 

 

© 著作权归作者所有

共有 人打赏支持
暗夜在火星

暗夜在火星

粉丝 151
博文 160
码字总数 310930
作品 1
广州
程序员
Docker多容器连接-以Nginx+PHP为例

Docker提供了多个容器之间访问的方法,最简单的方式是直接使用端口映射参数指定映射的端口或者映射所有端口,多个容器直接通过网络端口进行访问。 但网络端口映射方式并不是Docker中连接多个...

mylxsw
2015/06/02
0
0
php-fpm 参数及配置详解

一、php-fpm测试配置及平滑重启方法 二、php-fpm.conf配置文件详解 目前没有对文中的所有文字进行完整的翻译,如果有人需要很详尽的翻译,可以自己翻译下,此处只做简单的说明。...

woshiliwentong
2014/04/01
0
0
如何使用cgi-fcgi命令访问php-fpm实现HTTP请求

由于特殊的部署方式,一个nginx后面挂了多个php服务器,当需要遍历这些php服务器的时候,出现了一个蛋疼的问题,没有办法通过普通HTTP请求的方式遍历到所有的php服务器。 好在找到一个简单的...

anoty
2017/07/12
0
0
linux设置http/https proxy及忽略proxy的方法

一,场景: 有些linux服务器处于内网,并且没有公网ip,故要想与外网进行http/https通信只能通过nat或者加proxy的方式。nat服务器有网段的限制,而http/https proxy代理则没有,使用起来也方...

leejia1989
2017/12/07
0
0
ubuntu16.04 nginx+php+mysql配置

sudo apt update sudo apt-get install nginx sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install php-cli php-cgi php-mysql sudo apt-get instal......

一千零一夜个为什么
2016/12/08
50
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

阿里云API网关使用教程

API 网关(API Gateway)提供高性能、高可用的 API 托管服务,帮助用户对外开放其部署在 ECS、容器服务等阿里云产品上的应用,提供完整的 API 发布、管理、维护生命周期管理。用户只需进行简...

mcy0425
22分钟前
3
0
解决远程登陆误按ctrl+s锁屏假死恢复

使用putty时,偶尔发生屏幕假死,不能输入等情况。 后来发现,只要数据ctrl+s,就会假死;输入ctrl+q就可以恢复过来。 很多刚从windows转移到linux上来工作的朋友,在用vi/vim编辑文件时,常常...

HJCui
26分钟前
0
0
@Transactional

事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于...

asdf08442a
30分钟前
2
0
widows下强制解除8080端口占用问题

使用win+R打开命令窗口 输入以下命令查看哪个任务占用了8080端口 netstat -ano |findstr "8080" 然后通过任务id强制关闭占用该端口的进程 tskill 10044 // 自己的试情况而定,这个ID是LISTE...

_Artisan
39分钟前
2
0
productFlavors简单实用

最近项目中,不同环境需要配置的参数越来越多,为了减少修改代码次数。研究了一下productFlavors的使用方式,总结如下 1. as3.0以上版本使用productFlavors时需要指定一个flavorDimensions,...

火云
41分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部