为什么我的 $_ ENV 是空的?

我正在运行 Apache/2.2.11 (Win32) PHP/5.3.0,我在.htaccess 文件中执行了以下操作:

SetEnv FOO bar

如果打印出 PHP 文件中的 $_ENV变量,得到的是一个空数组。为什么我的环境变量不出现在那里?为什么一开始就是空的?

但是我确实找到了我的变量,但是它出现在 $_SERVER变量中。出于某种原因,它出现了两次。为什么会这样?

[REDIRECT_FOO] => bar
[FOO] => bar

看来我可以得到它使用 getenv('FOO'),所以也许我应该只是使用,而不是。但我还是有点好奇,究竟是什么原因导致了这种情况。这是 Windows 的问题吗?到底怎么回事?

56543 次浏览

$_ENV variables are imported from the environment under which PHP is running, and depending on your setup (the OS, your server, whether PHP runs as an Apache module or under FastCGI, etc.), this can vary greatly.

IIRC in a standard Apache+mod_php install on Windows, the only way to change variables in $_ENV is to change Windows' environment variables (see this). This can be significant when dealing with PHP extensions on Windows, because some of them (eg: php_ldap) are only configurable through environment vars on $_ENV.

REDIRECT_* variables appear if you are using RewriteRules. On my server they also appear just so. It might have something to do with running under FastCGI. And if combined with suexec, that's most likely to clean up the complete environment var pool. There might be additional configuration necessary to get them back, PassEnv particularily. As to why getenv() works for you, I have no clue. But all phenomena are specific to your server and php configuration. Ask on serverfault, they should know.

Turns out there was two issues here:

1. $_ENV is only populated if php.ini allows it, which it doesn't seem to do by default, at least not in the default WAMP server installation.

; This directive determines which super global arrays are registered when PHP
; starts up. If the register_globals directive is enabled, it also determines
; what order variables are populated into the global space. G,P,C,E & S are
; 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.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"

When I set the variables_order back to EGPCS, $_ENV is no longer empty.

2. When you use SetEnv in your .htaccess, it ends up in $_SERVER, not in $_ENV, which I gotta say is a tad confusing when it's named SetEnv...

# .htaccess
SetEnv ENV dev
SetEnv BASE /ssl/


# php
var_dump($_SERVER['ENV'], $_SERVER['BASE']);


// string 'dev' (length=3)
// string '/ssl/' (length=5)

3. The getenv function will always work and is not affected by the PHP setting for $_ENV Additionally it seems to do so insensitive to case, which might be useful.

var_dump(getenv('os'), getenv('env'));


// string 'Windows_NT' (length=10)
// string 'dev' (length=3)