getenv() vs. $_ENV in PHP
What is the difference between getenv()
and $_ENV
?
Any trade-offs between using either?
I noticed sometimes getenv()
gives me what I need, while $_ENV
does not (such as HOME
).
According to the php documentation about getenv, they are exactly the same, except that getenv
will look for the variable in a case-insensitive manner when running on case-insensitive file systems (like Windows). On Linux hosts it still works as case-sensitive. Most of the time it probably doesn't matter, but one of the comments on the documentation explains:
For example on Windows $_SERVER['Path'] is like you see, with the first letter capitalized, not 'PATH' as you might expect.
Because of that, I would probably opt to use getenv
to improve cross-platform behavior, unless you are certain about the casing of the environment variable you are trying to retrieve.
Steve Clay's comment in this answer highlights another difference:
Added
getenv()
advantage: you don't need to checkisset
/empty
before access.getenv()
won't emit notices.
I know that the comment in the docs says that getenv
is case-insensitive, but that's not the behaviour I'm seeing:
> env FOO=bar php -r 'print getenv("FOO") . "\n";'
bar
> env FOO=bar php -r 'print getenv("foo") . "\n";'
> env foo=bar php -r 'print getenv("foo") . "\n";'
bar
> env foo=bar php -r 'print getenv("FOO") . "\n";'
> php --version
PHP 5.4.24 (cli) (built: Jan 24 2014 03:51:25)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
Looking at the source code for the getenv
function, this is because there are three ways that PHP can fetch the environment variable:
- Via
sapi_getenv
(e.g. if it's getting the environment variable from Apache) - If on Windows, from
GetEnvironmentVariableA
. - If on non-Windows, from the
getenv
function provided bylibc
.
As far as I can tell, the only time when it will behave in a case-insensitive manner is on Windows because that's how the Windows environment variable API behaves. If you're on Linux, BSD, Mac, etc then getenv
is still case sensitive.
As mentioned by mario, $_ENV
is not always populated due to different configurations of variables_order
so it's best if you avoid $_ENV
if you don't control the server configuration.
So, for the most portable PHP code:
- Use
getenv
. - Use the correct case for the environment variable name.
Additionally $_ENV
is typically empty if variables_order
does't have E
listed. On many setups it's likely that only $_SERVER
is populated, and $_ENV
is strictly for CLI usage.
On the other hand getenv()
accesses the environment directly.
(Regarding the case-ambiguity, one could more simply employ array_change_key_case()
.)
I found getenv()
useful to avoid a strange PHP bug where sometimes $_SERVER
and $_ENV
was undefined if auto_globals_jit
was enabled (creating the _SERVER and _ENV variables when they're first used). Since then I began to to use it.