如何在运行 CLI 和 Apache2Handler 时将系统环境变量导入 PHP?

Posted

技术标签:

【中文标题】如何在运行 CLI 和 Apache2Handler 时将系统环境变量导入 PHP?【英文标题】:How to get system environment variables into PHP while running CLI & Apache2Handler? 【发布时间】:2012-11-14 03:03:02 【问题描述】:

我的系统是Ubuntu,我已经在/etc/environment中设置了我的环境变量。

如果我使用 CLI 运行 PHP 脚本 - 来自 /etc/environment 的环境变量会被识别。

但是,如果我通过 http://domain/test.php(即 apache2handler)执行 PHP 脚本,则完全相同的脚本会打印出 NULL,这意味着来自 /etc/environment 的环境变量未加载。

我所做的修复是在/etc/apache2/envvars 中添加变量,这解决了问题。

但这是两个不同的文件,因此必须保持同步。

如何让 PHP / Apache 加载并识别来自 /etc/environment(系统)的环境变量?

编辑:澄清一下,当我说“未加载到 PHP”时,这意味着来自 /etc/environment 的变量未在 $_SERVER$_ENVgetenv() 中设置,并且在 $GLOBALS 中不存在。换句话说,“没有加载到 PHP 中”。

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题。为了解决这个问题,我只是在/etc/apache2/envvars 中找到了/etc/environment

/etc/environment的内容:

export MY_PROJECT_PATH=/var/www/my-project
export MY_PROJECT_ENV=production
export MY_PROJECT_MAIL=support@my-project.com

/etc/apache2/envvars的内容:

# Load all the system environment variables.
. /etc/environment

现在,我可以在 Apache 虚拟主机配置文件和 PHP 中使用这些变量。

这是一个 Apache 虚拟主机的示例:

<VirtualHost *:80>
  ServerName my-project.com
  ServerAlias www.my-project.com
  ServerAdmin $MY_PROJECT_MAIL
  UseCanonicalName On

  DocumentRoot $MY_PROJECT_PATH/www

  # Error log.
  ErrorLog $APACHE_LOG_DIR/my-project.com_error.log
  LogLevel warn

  # Access log.
  <IfModule log_config_module>
    LogFormat "%h %l %u %t \"%m %>U%q\" %>s %b %D" clean_url_log_format
    CustomLog $APACHE_LOG_DIR/my-project.com_access.log clean_url_log_format
  </IfModule>

  # DocumentRoot directory
  <Directory $MY_PROJECT_PATH/www>
    # Disable .htaccess rules completely, for better performance.
    AllowOverride None
    Options FollowSymLinks Includes
    Order deny,allow
    Allow from All

    Include $MY_PROJECT_PATH/config/apache/inc.mime-types.conf
    Include $MY_PROJECT_PATH/config/apache/inc.cache-control.conf

    # Rewrite rules.
    <IfModule mod_rewrite.c>
      RewriteEngine on
      RewriteBase /

      # Include all the common rewrite rules (for http and https).
      Include $MY_PROJECT_PATH/config/apache/inc.rewriterules-shared.conf
    </IfModule>
  </Directory>
</VirtualHost>

这是一个如何使用 PHP 访问它们的示例:

<?php
header('Content-Type: text/plain; charset=utf-8');
print getenv('MY_PROJECT_PATH') . "\n" .
      getenv('MY_PROJECT_ENV') . "\n" .
      getenv('MY_PROJECT_MAIL') . "\n";
?>

【讨论】:

就我而言,在 /etc/environment 我必须将每个变量声明分成两行:首先是 export VAR,然后是 VAR="myVar",否则它将无法工作 在我的 (Ubuntu 16.04LTS) 系统上,我必须像这样组合 /etc/environment 中的导出语句:export MY_VAR='foo' Ubuntu 16.04 LAMP 堆栈:奇怪的是上述方法不起作用。但最后我能够通过在 /etc/apache2/sites-available 中使用 SetEnv 作为SetEnv VARNAME myvariable 来实现目标,感谢Set Environment Variables in Apache for Php 捎带这个,还有一个 PHP.ini 设置允许访问环境变量 - 它似乎在 7.2 中默认禁用。设置variables_order 中需要字符'E'。 php.net/manual/en/ini.core.php#ini.variables-order FWIW 我强烈反对使用 /etc/environment 文件来获取环境变量,尤其是使用带有这些“导出”行的 [技术上] 无效的环境格式。如果这样做,请注意每次重新启动时 Ubuntu snapd 服务将所有环境变量转储到系统日志!【参考方案2】:

在 ubuntu 上,PHP 对常规进程和 CLI 进程使用不同的 ini 文件。

应该有一些像/etc/php5/cli/php.ini/etc/php5/fpm/php.ini/etc/php5/php.ini这样的ini文件。打开相关的INI文件,修改

variables_order = "GPCS"

行到

variables_order = "EGPCS".

之后,您将获得在使用 $_ENV['varname'] 之前设置的环境变量。

来自 php.ini 关于variables_order

Abbreviations for the following respective super globals: GET, POST, COOKIE,
ENV and SERVER. There is a performance penalty paid for the registration of
these arrays and because ENV is not as commonly used as the others, ENV is
is not recommended on productions servers. You can still get access to
the environment variables through getenv() should you need to.

所以你可以尝试使用getenv() 而不是$_ENV[]。

【讨论】:

我知道 Ubuntu 上有两个不同的 php.ini 文件。而且它们都将可变顺序设置为“GPCS”。在这里添加'E'不会帮助我......因为我没有系统(ubuntu)env vars不在$ _ENV中,但根本没有被加载到PHP中,这意味着没有超全局变量列出它们,也没有$ GLOBALS,也不是 $_SERVER,也不是 $_ENV。为 100% 确定,我将添加“E”并检查。 正如预期的那样:/etc/environment 变量在使用 SAPI 作为 apache2handler 时不会加载到 PHP 全局变量中。 我已经使用php -i 来检查它加载了哪个php.ini 文件。更改variables_order 不起作用。 php -i 仍然报告 GPCS Mike,试着在 /etc/apache2/envvars 中设置你的环境变量,而不是 /etc/environment【参考方案3】:

最近我编写了一个库来从环境变量中获取值并解析为 PHP 数据类型。该库可用于将环境变量解析为 PHP 数据类型(如转换为整数、浮点数、空值、布尔值),解析 JSON 字符串等复杂数据结构,以及更多社区的贡献。

该库在此处可用:https://github.com/jpcercal/environment

将你的环境变量放入“/etc/environment”和“/etc/apache2/envvars”,重启你的Apache服务器并将你的环境变量加载到操作系统:

# source /etc/environment
# source /etc/apache2/envvars

并从环境变量(独立于环境 CLI、Apache、nginx、PHP 内置服务器等)中获取值:

<?php
// ...
require "vendor/autoload.php";
// ...
var_dump(Cekurte\Environment\Environment::get("YOUR_ENV_VARIABLE_NAME"));

尽情享受吧。

【讨论】:

【参考方案4】:

我认为您只能使用 .htaccess 设置环境变量:

SetEnv greet hello

PHP:

print $_SERVER["greet"];

【讨论】:

你读过这个问题吗? OP 知道如何设置环境变量。

以上是关于如何在运行 CLI 和 Apache2Handler 时将系统环境变量导入 PHP?的主要内容,如果未能解决你的问题,请参考以下文章

Angular-CLI 和 dotnet cli 如何编写命令同时观看? [复制]

如何使用CLI命令在输入文件参数上运行Python脚本来生成输出文件

如何在生产构建设置和启用 AOT 的情况下运行 angular cli ng 测试

即使在 cli 上间接指定了多次,如何让 sbt 只运行一次任务?

.NET CLI 如何在 Linux 上发布后运行应用程序

使用 vue-cli 时如何禁用在本地网络上运行应用程序?