Edit: as far as I can tell, my question is because of a defect in PHP. I've copied this question to the PHP bug tracker here: https://bugs.php.net/bug.php?id=74143 and plan to try and implement a fix.
The putenv function sets the value of an environment variable. According to the manual, putenv returns true on success, false on failure.
However, I'm finding that the putenv function sometimes returns true without updating the environment variable for the current session.
To reproduce this issue, set an environment variable in a webserver using PHP FPM, by using the fastcgi_param directive. This is incredibly useful, as it allows setting environment variables in isolation to other hosts on the same server.
Example nginx.conf:
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param TESTVAR_ENV old-value;
include fastcgi_params;
}
Example test.php:
var_dump(getenv("TESTVAR_ENV"));
var_dump(putenv("TESTVAR_ENV=new-value"));
var_dump(getenv("TESTVAR_ENV"));
Output of test.php:
string(12) "old-value"
bool(true)
string(12) "old-value"
As you can see:
Am I misunderstanding what the purpose of the putenv function is? Is there some missing documentation on the setenv manual page? How do I use putenv() to update existing environment variable?
In the Settings window, under Related Settings, click Advanced system settings. On the Advanced tab, click Environment Variables. Click New to create a new environment variable. Click Edit to modify an existing environment variable.
The putenv() function shall use the string argument to set environment variable values. The string argument should point to a string of the form " name= value ". The putenv() function shall make the value of the environment variable name equal to value by altering an existing variable or creating a new one.
A simple way to update the . env key value in laravel is to add the below code in the controller function where you want to change . env values. $key = 'VARIABLE_NAME'; $value = 'NEW VALUE'; file_put_contents(app()->environmentFilePath(), str_replace($key .
The difference to the setenv function is that the exact string given as the parameter string is put into the environment. If the user should change the string after the putenv call this will reflect automatically in the environment.
This is interesting. After investigating i found that there's an undocumented parameter for getenv()
.
Calling putenv("TESTVAR_ENV=new-value")
followed by getenv("TESTVAR_ENV", true)
returns new-value
as expected. However getenv("TESTVAR_ENV", true)
returns false when called without explicitly setting the value first.
Reading from the source it seems that if local_only is set to false (the default), the value is fetched using sapi_getenv
, whereas with local_only set to true the native getenv
is used.
Furthermore, if sapi_getenv
doesn't return a value, then getenv
is called as a fallback. Meaning if you don't set TESTVAR_ENV
in nginx/Apache configuration at all, putenv
/getenv
works as expected.
So to recap:
getenv(name)
searches from SAPI's (php-fpm) internal environment table, and fallbacks to OS's environment if variable is not set.getenv(name, true)
searches only from OS's environment, which doesn't necessarily (depending on the SAPI) contain variables registered in the web server's configuration.putenv()
always only updates OS's environment.I used the following to test this:
header("Content-Type: text/plain");
dump_env();
echo 'getenv("TESTVAR_ENV") => ' .
var_export(getenv("TESTVAR_ENV"), true) . "\n";
echo 'getenv("TESTVAR_ENV", true) => ' .
var_export(getenv("TESTVAR_ENV", true), true) . "\n";
echo "-----------\n";
echo 'putenv("TESTVAR_ENV=new-value") => ' .
var_export(putenv("TESTVAR_ENV=new-value"), true) . "\n";
dump_env();
echo 'getenv("TESTVAR_ENV") => ' .
var_export(getenv("TESTVAR_ENV"), true) . "\n";
echo 'getenv("TESTVAR_ENV", true) => ' .
var_export(getenv("TESTVAR_ENV", true), true) . "\n";
function dump_env() {
echo "--- env ---\n" . `env` . "-----------\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With