Редактировать: насколько я могу судить, мой вопрос из-за дефекта в PHP. Я скопировал этот вопрос в трекер ошибок PHP здесь: https://bugs.php.net/bug.php?id=74143 и планируем попробовать и исправить.
Функция putenv устанавливает значение переменной окружения. Согласно инструкции, putenv возвращает true в случае успеха, false в случае неудачи.
Однако я обнаружил, что функция putenv иногда возвращает true, не обновляя переменную среды для текущего сеанса.
Чтобы воспроизвести эту проблему, установите переменную среды на веб-сервере с помощью PHP FPM с помощью директивы fastcgi_param. Это невероятно полезно, поскольку позволяет устанавливать переменные среды изолированно от других хостов на том же сервере.
Пример nginx.conf:
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param TESTVAR_ENV old-value;
include fastcgi_params;
}
Пример test.php:
var_dump(getenv("TESTVAR_ENV"));
var_dump(putenv("TESTVAR_ENV=new-value"));
var_dump(getenv("TESTVAR_ENV"));
Вывод test.php:
string(12) "old-value"bool(true)
string(12) "old-value"
Как вы видете:
Я неправильно понимаю, какова цель функции putenv? Есть ли какая-то недостающая документация на странице руководства setenv? Как использовать putenv () для обновления существующей переменной среды?
Это интересно. После расследования я обнаружил, что есть недокументированный параметр за getenv()
,
призвание putenv("TESTVAR_ENV=new-value")
с последующим getenv("TESTVAR_ENV", true)
возвращается new-value
как и ожидалось. тем не мение getenv("TESTVAR_ENV", true)
возвращает false при вызове без явной установки значения первым.
Чтение из источник кажется, что если local_only имеет значение false (по умолчанию), значение выбирается с помощью sapi_getenv
тогда как с local_only установить истинный родной getenv
используется.
Кроме того, если sapi_getenv
не возвращает значение, то getenv
называется запасным вариантом. Смысл, если вы не установите TESTVAR_ENV
в конфигурации nginx / Apache, putenv
/getenv
работает как положено.
Итак, резюмируем:
getenv(name)
выполняет поиск из таблицы внутренней среды SAPI (php-fpm) и выполняет откат к среде ОС, если переменная не установлена.getenv(name, true)
поиск выполняется только в среде ОС, которая не обязательно (в зависимости от SAPI) содержит переменные, зарегистрированные в конфигурации веб-сервера.putenv()
всегда только обновляет среду ОС.Я использовал следующее, чтобы проверить это:
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";
}
Других решений пока нет …