Php переменные окружения. Переменные окружения CGI. Формируемые сервером переменные

Внимание! Статья написана под Windows 7, но принципиальных отличий в добавлении PHP в переменные среды в другие версии (Window XP, Windows Vista, Windows 8, ...) нет.

Информация! Все пути в настройках будут указаны исходя из того, что Denwer установлен в папку D:/web . При использовании данных из статьи не забудьте поменять этот путь на свой.

Для удобного использования PHP в консоле Windows необходимо настроить переменные среды. Иначе при работе с PHP через консоль вместо команды php Вам будет необходимо писать полный путь к файлу php.exe .

Предположим, что Denwer у нас установлен в папку D:/web .

Кликаем правой кнопкой мыши по иконке "Компьютер" Свойства:

Дополнительные параметры системы:

Вкладка "Дополнительно", кнопка "Параметры среды...":

Группа "Системные параметры", выделите переменную Path и нажмите кнопку изменить:

Добавьте строку D:\web\usr\local\php5; и нажмите кнопку "Ок":

Перезапустите Denwer. Теперь Вы можете открыть консоль (Win + R и введите cmd) и проверить работу PHP , введите команду:

Для исправления этих ошибок откройте файл D:/web/usr/local/php5/php.ini . Найдите переменные extension_dir , zend_extension , session.save_path и установите для них следующие значения.

Переменные окружения, используемые в конфигурации, являются на сегодняшний день основным методом установки в приложении таких настроек, как учетные данные базы, API ключи, секретные ключи и всего, что является различным в зависимости от того, где развертывается приложение . Сейчас такие настройки попадают в код через окружение, вместо прямого прописывания в файлах конфигурации или, того хуже, хардкода прямо в коде.

Давайте подробнее взглянем на то:

  • как это работает?
  • действительно ли это хорошая идея?
  • как с ними работать в PHP?
  • и в заключение на некоторые рекомендации и распространенные ошибки, которых следует избегать - на те ловушки, на которые мы наткнулись в реальном мире!

Мы не будем рассматривать как настроить переменные окружения в вашем веб-сервере / Docker-е / crontab-ах... т. к. это зависит от системы, программного обеспечения, а мы хотим сосредоточиться на самих переменных окружения.

Если ваш хостинг использует Docker Swarm или AWS , все будет немного по-другому, например, т. к. они решили подсовывать файлы на файловую систему вашего контейнера, чтобы внедрить ваши секретные ключи, а не использовать переменные окружения. Это очень специфично для этих платформ и не является распространённым вариантом для всех.

Env vars 101

При запуске программы, она наследует все переменные окружения от своих родителей. Так что если вы установите переменную YOLO в значение covfefe в bash, а затем выполните команду, вы сможете прочитать YOLO в любом дочернем процессе.

$ YOLO=covfefe php -r "echo getenv("YOLO");" covfefe

Поскольку эта переменная определена только локально, мы не можем прочитать её из другого терминала (другого родителя). Идея в том, чтобы убедиться, что ваше приложение всегда наследует нужные переменные.

Вы можете посмотреть все переменные окружения в командной строке, выполнив следующую команду, но вы не увидите переменной YOLO , т. к. она была передана только в команду php "на лету", а не установлена в текущем процессе:

Вы можете установить переменную окружения с помощью export <имя>=<значение> :

$ export YOLO=covfefe

Имена переменных чувствительны к регистру и соглашение заключается в использовании имён только на английском, в верхнем регистре, с _ в качестве разделителя (т. н. "змеиный" стиль в верхнем регистре). Вы уже наверняка знаете некоторые переменные - такие как PATH , DISPLAY , HTTP_PROXY …

Лучшие практики на сегодня

josegonzalez/dotenv , ориентирована на безопасность:

Эта библиотека не заполнит суперглобальные переменные по умолчанию:

$Loader = new josegonzalez\Dotenv\Loader("path/to/.env"); // Парсим файл.env: $Loader->parse(); // Отправляем результат парсинга.env в переменную $_ENV: $Loader->toEnv();

Она поддерживает обязательные переменные, фильтрацию, и может выбрасывать исключения, когда переменная перезаписывается.

symfony/dotenv , новый малыш на этом поприще:

Доступен начиная с Symfony 3.3. Этот компонент заботится о.env -файле, как остальные, и тоже заполняет суперглобальные массивы:

$dotenv = new Symfony\Component\Dotenv\Dotenv(); $dotenv->load(__DIR__."/.env"); $dbUser = getenv("DB_USER"); $dbUser = $_ENV["DB_USER"]; $dbUser = $_SERVER["DB_USER"];

Вы не должны использовать её для получения ваших значений, поэтому я предлагаю вам вместо этого обращаться к $_SERVER - к тому же есть небольшая разница в производительности между обращением к массиву и вызовом функции в пользу массивов.

Переменные окружения - всегда строки

Одной из главных проблем является то, что сейчас в PHP есть указание типов, а наши настройки не всегда правильно набраны.

Class Db { public function connect(string hostname, int port) { } } // Это не будет работать: $db->connect($_SERVER["DATABASE_HOSTNAME"], $_SERVER["DATABASE_PORT"]);

В Symfony теперь можно преобразовывать variables , а даже больше - чтение файла, декодирование json...…

Переменные окружения везде или нет

На данный момент существует много споров между использованием переменных окружения, файлов, или их смеси: переменная окружения ссылается на файл конфигурации. Дело в том, что несмотря на то, что это считается лучшей практикой, переменные окружения не представляют больших преимуществ...

Но если правильно использовать, в приложении на Symfony, например, переменные окружения могут быть изменены "на лету" - без очистки какого-либо кеша, без обращения к файловой системе, без развертывания кода: просто перезапустив процесс, например.

Тенденция иметь только одну переменную, как APP_CONFIG_PATH , и читать её через "%env(json:file:APP_CONFIG_PATH)%" для меня выглядит как заново изобретать старый добрый parameters.yml , если файл не управляется автоматически с помощью надежного инструмента (как AWS Secret Store). И также есть envkey.com , который позволяет управлять вашими переменными окружения из одного места, не возясь с файлами самостоятельно, мне нравится такой подход, т. к. это гораздо проще!

Непосредственно перед запуском сценария сервер передает ему некие переменные окружения с информацией. В определенных переменных содержатся некоторые заголовки, но, как уже говорилось, не все (получить все заголовки нельзя). Переменные окружения в языке PHP можно использовать как самые обыкновенные переменные. Переменные окружения делятся на четыре большие группы:

  • Формируемые сервером переменные;
  • Специальные переменные сервера Apache;
  • Переменные HTTP-полей запроса;
  • Переменные SSL-соединения (защищенного соединения).

Рассмотрим первые три группы переменных окружения:

Формируемые сервером переменные:

Переменная окружения

AUTH_TYPE Используется схема аутентификации. Обычно "BASIC"
CONTENT_LENGTH Длина содержимого, например, text/html
CONTENT_TYPE MIME-тип содержимого, например, text/html
GETAWAY_INTERFACE Версия CGI, например CGI/1.1
PATH_INFO HTTP-путь к сценарию
PATH_TRANSLATED Полный путь к сценарию
REMOTE_ADDR IP-адрес запрашиваемого компьютера-клиента
REMOTE_HOST Доменное имя запрашивающего компьютера (если доступно). Доменное имя определяется web-сервером с помощью службы DNS. Директива HostNameLookups сервера Apache разрешает (или запрещает) преобразование IP-адреса в доменное имя.
REMOTE_PORT Порт, закрепленный за браузером для получения ответа от сервера
REMOTE_USER Имя пользователя, прошедшего аутентификацию
QUERY_STRING Строка переданных серверу параметров
SERVER_ADDR IP-адрес сервера
SERVER_NAME Доменное имя сервера. Определяется директивой ServerName файла конфигурации
SERVER_PORT TCP-порт Web-сервера. Обычно 80
SERVER_PROTOCOL Версия протокола HTTP. Например, HTTP/1.1
SERVER_SOFTWARE Программное обеспечение сервера
SCRIPT_NAME HTTP-путь к сценарию
SCRIPT_FILENAME Имя файла сценария в файловой системе сервера (физический путь). Например, /var/www/cgi-bin/script.cgi

Специальные переменные сервера Apache:

Переменные HTTP-полей запроса:

Переменная окружения

Описание переменной окружения

HTTP_HOST Имя виртуального хоста, которому адресован запрос
HTTP_USER_AGENT Программное обеспечение удаленного пользователя. Обычно данная переменная окружения содержит название и версию браузера
HTTP_ACCEPT Список поддерживаемых клиентов типов содержимого. В последнее время вместо списка браузеры возвращают значение *.*, что означает "все типы"
HTTP_ACCEPT_LANGUAGE Список поддерживаемых языков в порядке предпочтения, например, ru, en
HTTP_ACCEPT_ENCODING Список поддерживаемых методов сжатия
HTTP_ACCEPT_CHARSET Список поддерживаемых кодировок
HTTP_CONNECTION

Тип соединения. Возможны два варианта:

  • Keep-alive - если после ответа на запрос не нужно разрывать соединение;
  • Close - если нужно закрыть соединение сразу после ответа на запрос.
HTTP_REFERER Значение поля REFERER. В этом поле браузер передает URL ресурса, который ссылается на наш сервер. Например, если пользователь перешел на сайт со страницы http://www.somehost.com/page.php, то значение поля REFERER будет http://www.somehost.com/page.php.
HTTP_X_FORWARDED_FOR Если пользователь работает через прокси-сервер, то в этом поле будет IP-адрес компьютера, обратившегося к прокси-серверу. Если данное поле уже содержит значение, то новое значение будет добавлено через запятую.

Непосредственно перед запуском сценария сервер передает ему некие переменные окружения с информацией. В определенных переменных содержаться некоторые заголовки, но не все (получить все заголовки нельзя).

HTTP_ACCEPT - В этой переменной перечислены все MIME-типы данных, которые могут быть восприняты браузером. Строка */* означает, что браузер понимает любой тип.

HTTP_ACCEPT= */*

HTTP_REFERER - Эта переменная представляет сведения о странице, с которой пользователь попал на данную. Эту переменную можно использовать, например, для отслеживания перемещения пользователя по вашему сайту, а затем просматривать наиболее популярные маршруты.

HTTP_REFERER= http://www.spravkaweb.ru/

HTTP_COOKIE - В этой переменной храняться все Cookies в URL-кодировке.

HTTP_COOKIE=

HTTP_USER_AGENT - Идентифицирует браузер пользователя. Для установления типа браузера нужно проверить эту строку на наличие слов: если браузер - Internet Explorer, то будет присутствовать подстрока MSIE, а если в наличии лишь слово Mozilla, то это Netscape.

HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0)

У вас Internet Explorer

HTTP_HOST - Содержит доменное имя Web-сервера, на котором запустился сценарий. Эту переменную достаточно удобно использовать, например, для генерации полного пути, который требуется в заголовке Location, чтобы не привязываться к конкретному серверу.

HTTP_HOST= www.spravkaweb.ru

HTTP_FROM - Адрес электронной почты пользователя, направившего запрос.

HTTP_FROM=

SERVER_NAME - Доменное имя или IP-адрес сервера.

SERVER_NAME= www.spravkaweb.ru

SERVER_SOFTWARE - Имя и версия программы-сервера, отвечающей на запрос клиента.

SERVER_SOFTWARE= Apache/1.3.33 (Unix) mod_jk/1.2.8 mod_auth_passthrough/1.8 mod_log_bytes/1.2mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_ssl/2.8.22 OpenSSL/0.9.7a PHP-CGI/0.1b

SERVER_PORT - Эта переменная содержит порт сервера, к которому обратился браузер пользователя. Обычно это 80. Переменная так-же может применяться для формирования параметра заголовка Location.

SERVER_PORT= 80

SERVER_PROTOCOL - Переменная содержит имя и версию информационного протокола, который был использован для запроса.

SERVER_PROTOCOL= HTTP/1.0

REMOTE_ADDR - Эта переменная содержит IP-адрес (или доменное имя) узла пользователя, на котором был запущен браузер.

REMOTE_ADDR= 212.94.114.177

REMOTE_PORT - Порт, который закрепляется за браузером пользователя для получения ответа сервера.

REMOTE_PORT= 4277

REMOTE_USER - Идентификационное имя пользователя, посылающего запрос.

REMOTE_USER=

SCRIPT_NAME - Содержит имя файла, содержащего данный сценарий. Эту переменную удобно использовать при формировании заголовка Location при переадресации на себя (self-redirect), а также для подставления значения атрибута action тега

на странице, которую вызывает сценарий при запуске без параметров (для того чтобы не привязываться к конкретному имени сценария).

SCRIPT_NAME= /pril.php

DOCUMENT_ROOT - Корневой каталог дерева Web-документов.

DOCUMENT_ROOT= /home/spravka/public_html

REQUEST_METHOD - Метод, который применяет пользователь при передаче данных. Надо заметить, что грамотно составленный сценарий должен сам определять на основе этой переменной, какой метод задействует пользователь, и принимать данные из соответствующего источника, а не расчитывать, что передача будет осуществляться, например, только методом POST.

REQUEST_METHOD= GET

QUERY_STRING - Содержит параметры, которые в URL указаны после вопросительного знака. Напомним, что они доступны как при методе GET, так и при методе POST (если в последнем случае они были определены в атрибуте action тега ).

QUERY_STRING= ss=getenv

PATH_INFO - Содержит дополнительную информацию о пути.

PATH_INFO=

PATH_TRANSLATED - Та же информация, что и в переменной PATH_INFO с префиксом, задающим путь к корневому каталогу дерева Web-документов.

PATH_TRANSLATED=

CONTENT_TYPE - Медиа-тип данных запроса.

CONTENT_TYPE=

CONTENT_LENGTH - Возвращает количество байт данных, присланных пользователем. Эту переменную необходимо анализировать, если вы занимаетесь приемом и обработкой POST-формы.

GATEWAY_INTERFACE - Версия CGI, которую использует сервер.

GATEWAY_INTERFACE= CGI/1.1


Переменные окружения

Переменные окружения:




echo "Вы пришли из: ".getenv("HTTP_REFERER")."
";
$br=getenv("HTTP_USER_AGENT");
if(strpos($br,"MSIE")!==false) echo "У вас Internet Explorer
";
else echo "У вас Netscape или др.
";
echo "Ваш IP: ".getenv("REMOTE_ADDR")."
";
echo "Вот параметры в строке браузера: ".getenv("QUERY_STRING");
?>