【问题标题】:How to get PHP to be able to read system environment variables如何让 PHP 能够读取系统环境变量
【发布时间】:2015-08-29 14:55:52
【问题描述】:

我在 Centos 上使用 PHP 作为 PHP-FPM。我正在尝试遵循 http://12factor.net/ 将设置存储在环境变量中的准则。

我在 /etc/profile.d 中创建了一个文件,用于设置我想要的环境变量,环境变量在通过 Bash 在 CLI 中测试时出现,即运行 bash 脚本:

echo $SOME_SERVER_SETTING

显示正确的输出。

我已将 clear_env 设置设置为 false 并将 variables_order 设置为 EGPCS,但是,我设置的变量在 PHP 中既不显示 getenv('SOME_SERVER_SETTING') 也不显示 var_dump($_ENV)

还需要设置哪些其他设置以允许 PHP-FPM 接收所有服务器环境变量,尤其是通过 Centos 上 /etc/profiles.d 中的 shell 脚本设置的那些?

【问题讨论】:

    标签: php centos environment-variables


    【解决方案1】:

    使用 Systemd 服务和 PHP 5.6.4 在 Centos 7 上测试

    打开

    /etc/php.ini
    

    查找

    variables_order = "GPCS"
    

    替换为

    variables_order = "EGPCS"
    # http://php.net/manual/en/ini.core.php#ini.variables-order
    

    打开

    /etc/php-fpm.d/www.conf (maybe /etc/php5/fpm/pool.d/www.conf)
    (do not confuse with /etc/php-fpm.conf)
    

    如果存在则查找

    clear_env = yes
    

    替换或添加

    clear_env = no
    # http://php.net/manual/en/install.fpm.configuration.php
    

    打开

    /etc/environment
    

    添加

    #any variables you need, for example:
    MY_VAR=1234
    

    在 shell 中运行以进行检查

    source /etc/environment
    echo $MY_VAR # 1234
    

    在外壳中运行

    ln -fs /etc/environment /etc/sysconfig/php-fpm
    systemctl daemon-reload && service php-fpm restart
    

    ...测试

    打开

    index.php # in your project folder, running with php-fpm
    

    添加

    var_dump(getenv('MY_VAR'), $_ENV['MY_VAR']);exit;
    

    在浏览器中运行

    http://mylink.to.project/index.php   
    string(4) "1234"
    string(4) "1234"
    

    尽情享受吧!

    【讨论】:

    • hmm,但是您在此处对 /etc/environment 中的变量进行了硬编码。为什么不用 export=val 添加而不是硬编码呢?
    • 由你决定,这是一个例子
    【解决方案2】:

    FastCGI 设置中的环境变量由 FPM 进程的客户端设置为输入,例如 NginX。它们作为标头发送到 FastCGI 服务器,FastCGI 服务器对其进行解释并相应地设置它们,以便您使用 getenv 读出。

    如果您实际上使用的是 NginX,请查找 fastcgi_param 指令。您还可以在 php5-fpm 的池配置中设置环境变量,具体取决于您的用例。

    【讨论】:

      【解决方案3】:

      您需要从正确的位置读取环境变量。 PHP 为此创建了一个超级全局变量:$_ENV 因此,您可以通过访问该变量中的某个元素来访问单个变量,该变量包含一个数组:echo $_ENV['SOME_SERVER_SETTING'];

      我不知道为什么您上面的示例应该在 CLI 上运行。超级全局变量是记录在案的位置和作品。

      您的问题可能是没有为 http 服务器进程设置变量。通常,像/etc/profile.d 中的脚本在登录时执行。因此,当用户在系统内部创建会话时。但是对于作为系统服务器启动的 http 服务器来说,这永远不会发生。不执行登录,不执行配置文件脚本,不设置环境变量。

      要解决这个问题,你可以

      • 在服务的启动脚本中设置环境变量
      • 在主机配置或.htaccess样式文件中设置变量
      • 自动添加设置变量的脚本

      【讨论】:

      • 我澄清了 - 那是在 CLI 中使用 Bash 而不是 PHP 进行测试。您能否扩展“在服务的启动脚本中设置环境变量”。我在登录服务器时进行测试,并通过 init.d 脚本重新启动 PHP-FPM。我原以为这会带来环境变量,因为 PHP-FPM 进程是从登录的根进程启动的。此外,仅调用在 init.d 脚本中设置环境变量的脚本似乎没有任何改变。
      • 在您的个人会话中设置的环境变量(通常)不会移交给您通过某些初始化脚本启动的进程,因为该服务是在另一个用户帐户下执行的。即使是这样,它也不能真正解决您的问题,因为在正常情况下您不会手动启动该服务。相反,它将由未发生登录的引导序列启动。正如您所说,那个“根进程”没有执行任何登录。
      • 我猜你是对的,在启动脚本中设置变量将不起作用......否则手动运行该脚本将移交显然不是这种情况的变量。虽然......实际上不确定。除了设置它们之外,尝试“导出”它们。
      【解决方案4】:

      安全原因:-)

      参见/etc/php5/fpm/pool.d/www.conf(debian 位置,在 CentO 上可能不同)

      ; Clear environment in FPM workers
      ; Prevents arbitrary environment variables from reaching FPM worker processes
      ; by clearing the environment in workers before env vars specified in this
      ; pool configuration are added.
      ; Setting to "no" will make all environment variables available to PHP code
      ; via getenv(), $_ENV and $_SERVER.
      ; Default Value: yes
      ;clear_env = no 
      
      ; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
      ; the current environment.
      ; Default Value: clean env
      ;env[HOSTNAME] = $HOSTNAME
      ;env[PATH] = /usr/local/bin:/usr/bin:/bin
      ;env[TMP] = /tmp
      ;env[TMPDIR] = /tmp
      ;env[TEMP] = /tmp
      

      【讨论】:

      • 我在问题中说我已经将 clear_env 设置为 no。
      • 您真的将其设置为“否”吗?在您最初的帖子中,您写了“假”。我只得到 USER 和 HOME 环境变量,但如果我在上面的文件中设置 clear_env = no 我也会得到 TERM PATH PWD 等
      • 我是通过 php_admin_value[clear_env] 设置的——这就是它不起作用的原因。
      猜你喜欢
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2018-07-01
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多