Как использовать putenv () для обновления существующей переменной среды?

Редактировать: насколько я могу судить, мой вопрос из-за дефекта в 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"

Как вы видете:

  1. существующее значение успешно прочитано getenv,
  2. функция putenv возвращает true, указывая на успех,
  3. новое значение на самом деле не установлено, что невероятно запутанно.

Я неправильно понимаю, какова цель функции putenv? Есть ли какая-то недостающая документация на странице руководства setenv? Как использовать putenv () для обновления существующей переменной среды?

11

Решение

Это интересно. После расследования я обнаружил, что есть недокументированный параметр за 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";
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]