php - 为什么已经定义的环境变量需要 putenv()?

标签 php apache postgresql environment-variables

php用作 apache模块,来自 apache 的环境变量 SetEnv指令可用于 php 的 getenv() , 但它似乎不适用于 C通过 stdlib 的 getenv() 扩展.至少它发生在 pgsql 上模块。

如果用php代码重新实例化变量:

putenv("varname=".getenv("varname"));

然后它就可以用于扩展的代码。

问题:为什么需要重新实例化?核心 php 环境与“标准”(stdlib)环境有何不同?

这发生在:PHP Version 5.3.10-1ubuntu3.17在 Ubuntu 12.04 中,作为 apache 模块。从命令行运行时,不需要上述解决方法。 来自另一个问题:Using .pgpass from Apache libphp5.so看来这个解决方法对于 FreeBSD 下的 php-5.4 也是必需的,所以它不仅仅是 Ubuntu 或 php-5.3。

它不依赖于variables_orderE在里面。我都试过了 EGPCSGPCS , 和 $_ENV E 时未填充正如预期的那样不存在,但这不会改变 getenv() 的结果, 作为 documented ,或者显然是 stdlib 的 getenv() 的结果来自内部扩展。


问题演示 pgsql模块。它建立在 libpq 之上用 C 编写的共享库,它调用 getenv()在少数可选 PG*环境变量。

在apache配置文件中,在一个<VirtualHost>下,我将其设置为使连接尝试失败:

SetEnv PGHOST doesnotexist

并且没有在 pg_connect 中指定主机打电话,所以PGHOST在场时必须带走。

第一次尝试:

$v=getenv("PGHOST");
echo "PGHOST=$v\n";

$cnx=pg_connect("user=daniel");
if ($cnx) {
   echo "Connection is successful.";
} 

结果:

PGHOST=doesnotexist
Connection is successful.

So PGHOST is getting ignored, despite being in the environment.

Second try, now putting again PGHOST into the environment even though it's already there:

$v=getenv("PGHOST");
echo "PGHOST=$v\n";
putenv("PGHOST=".getenv("PGHOST"));
$cnx=pg_connect("user=daniel");
if ($cnx) {
   echo "Connection is successful.";
} 

结果(未能连接到指定主机,如预期):

PGHOST=doesnotexist
Warning: pg_connect(): Unable to connect to PostgreSQL server:
could not translate host name "doesnotexist" to address:
Name or service not known in /var/www/test/pgtest2.php on line 8

最佳答案

原因是这样的:

您从 getenv()[PHP](php 函数)获得的环境值与您使用 getenv()[C](the C库函数)。 getenv()[PHP] 所做的是检查已注册的 sapi 是否匹配( http://lxr.php.net/xref/PHP_5_6/ext/standard/basic_functions.c#3999 )。

apache2 sapi 通过自己的环境上下文 (http://lxr.php.net/xref/PHP_5_6/sapi/apache2handler/sapi_apache2.c#253) 执行此操作,而不是来自 apache 进程本身的标准操作系统环境。

只有当没有找到匹配时,它才会检查实际进程的环境。所以这就是为什么 getenv()[PHP] 返回一个值,而 getenv()[C] 没有。

现在,“hack”也很简单:putenv()[PHP],将给定的键/值存储在运行进程的环境中,这就是为什么它可以稍后由 getenv()[c] 找到。

关于php - 为什么已经定义的环境变量需要 putenv()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29700814/

相关文章:

javascript - $.post 不能与 $J = jQuery.noConflict(); 结合使用

php - pg_query() : Query failed: ERROR: operator does not exist: integer ~~ unknown\n

Java Apache POI FINE_DOTS 无法解析或不是字段

ruby-on-rails - 在 postgresql gem 上 bundle 安装失败。 (是的,已安装 postgres)

php - Symfony2 : Get Route Path

PHP MySQL - 在 <Select></select> 表单上显示值

php - Laravel 日期未插入,更新数据库表

javascript - Apache 服务器上 WebSocket 的开销

sql - Postgresql:通过通配符和带索引的比较运算符在 JSON 数组中查找值

PostgreSQL:语法错误在或接近 TO