10.4. Переменные окружения
Когда запускается какая-либо Unix-программа, доступная ей среда включает в себя набор связей "имя-значение" (как имена, так и значения являются строками). Некоторые из них устанавливаются пользователем вручную, другие - системой во время
10.4.1. Системные переменные окружения
Существует множество широко известных переменных окружения, значения которых программа может получить при запуске из оболочки Unix. Данные переменные (особенно НОМЕ) часто требуется оценить до считывания локального файла
автора
Роббинс Арнольд
10.4.2. Пользовательские переменные окружения
Несмотря на то, что приложения могут свободно интерпретировать переменные окружения за пределами определенного системой набора, в настоящее время фактическое использование такой возможности является довольно необычным.
Из книги
автора
10.4.3. Когда использовать переменные окружения
Общим для пользовательских и системных переменных окружения является то обстоятельство, что в них содержатся данные, хранение которых в большом количестве конфигурационных файлов было бы утомительным. И крайне утомительным
Из книги
автора
14.4. Переменные окружения
Иногда необходимо обращаться к переменным окружения, которые являются связующим звеном между программой и внешним миром. Переменные окружения - это просто метки, связанные с некоторым текстом (обычно небольшим); в них хранятся, например, пути к
Из книги
автора
Функции и переменные. Локальные переменные
Объявленные ранее функции создают внутри своего тела собственные переменные. Это так называемые локальные переменные. Такие переменные доступны только внутри тела функции, в котором они объявлены. При завершении выполнения
Из книги
автора
22.3.3. Переменные окружения
В программах, работающих с возможностями setuid или setgid, нужно проявлять особую осторожность с установками окружения. Эти переменные определяются пользователем, активизировавшим программу, тем самым открывается путь для атак. Самая явная атака
Из книги
автора
Переменные окружения
Переменные окружения - глобальные установки системы, которые используются при первоначальной загрузке операционной системы. В Windows, Linux и в большинстве систем UNIX сервер Firebird распознает и использует некоторые переменные окружения, если они
Из книги
автора
Где устанавливаются переменные окружения
WindowsТип переменных окружения и способ их установки меняется от одной версии Windows к другой. В табл. 3.1 показаны типы (если применимы) и способы установки значений переменным окружения.Таблица 3.1. Установки переменных окружения для
Из книги
автора
Глава 2
Аргументы, опции и переменные окружения
Первой задачей любой программы обычно является интерпретация опций и аргументов командной строки. Данная глава рассматривает, как программы С (и С++) получают аргументы своей командной строки, описывает стандартные
Когда браузер запрашивает от веб-сервера документ, он также пересылает на сервер техническую информацию об определённых параметрах браузера и операционной системы. Веб-сервер
в свою очередь одновременно с документом возвращает некоторые
свои характеристики. Таким образом, браузер и веб-сервер обмениваются данными, которые
называются переменные окружения. Эти переменные можно применять в своих целях
и отображать их на веб-странице.
При использовании SSI общий синтаксис вывода определенной переменной окружения
будет следующий.
Некоторые переменные с их описанием перечислены в табл. 1. Заметьте,
что все имена пишутся заглавными символами. Хотя это условие и необязательно,
именно такая форма записи является традиционной и устоявшейся.
Табл. 1. Список переменных окружения
Переменная
|
Описание
|
---|
DOCUMENT_ROOT
|
Путь к корневой папке сайта. Для локального веб-сервера значение может
принимать вид z:/home/сайт/www, а в других случаях зависит от операционной
системы сервера и используемого программного обеспечения.
|
GATEWAY_INTERFACE
|
Версия CGI (Common Gateway Interface, общий шлюзовый интерфейс). Значение
обычно равно CGI/1.1
.
|
HTTP_ACCEPT
|
Типы файлов, которые способен принять браузер. В качестве значения возвращается
список поддерживаемых MIME-типов разделенных между собой запятой, например: text/html,
application/xhtml+xml
.
|
HTTP_CONNECTION
|
Тип соединения браузера с веб-сервером. Так, значение keep-alive
означает, что браузер поддерживает постоянное соединение с сервером. При
этом в течение одного сеанса соединения разрешено делать несколько запросов.
Повторного соединения в таком случае уже не происходит.
|
HTTP_HOST
|
Доменное имя сайта. Обычно различают имена с префиксом www (www..ru). Переменная вернёт тот адрес сайта, который указан
в адресной строке браузера.
|
HTTP_REFERER
|
Адрес страницы, с которой пользователь перешел на данный сайт, он еще
называется реферер.
|
HTTP_USER_AGENT
|
Идентификатор используемого браузера и операционной системы. В качестве
значения возвращается строка, содержащая ключевые слова. Например, следующая
строка
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
говорит, что пользователь использует браузер Firefox 6.0.2 под операционной
системой Windows 7.
|
QUERY_STRING
|
Запрос, который указан в адресной строке после вопросительного знака (?).
Обычно пишется в форме «переменная=значение», где переменные разделяются
между собой амперсандом (&).?id=5&slv=34
будет возвращено значение id=5&slv=34
.
|
REMOTE_ADDR
|
IP-адрес посетителя сайта.
|
REQUEST_METHOD
|
Метод отправки данных на сервер. По умолчанию применяется метод GET.
|
REQUEST_URI
|
Адрес запрашиваемого документа. Отсчёт ведётся от корня сайта, т.е..html вернется значение 1.html
.
|
SERVER_ADDR
|
IP-адрес компьютера, на котором размещается сайт.
|
SERVER_ADMIN
|
Адрес электронной почты администратора сайта.
|
SERVER_NAME
|
Имя сервера.
|
SERVER_PORT
|
Порт, по которому ожидается получение данных.
|
SERVER_PROTOCOL
|
Протокол для получения и отправки данных. Значение обычно равно HTTP/1.1
.
|
SERVER_SOFTWARE
|
Программное обеспечение установленное на сервере. Для веб-сервера Apache
возвращается номер версии (Apache/2.2.4
),
а также версия PHP (PHP/5.3.3
).
|
В примере 1 показано использование переменных окружения для отображения
на веб-странице требуемой информации.
Пример 1. Вывод значения переменной DOCUMENT_ROOT
SSI
Путь к корневой папке сайта:
В результате выполнения примера будет выведена следующая строка: Путь к корневой папке сайта: /home/сайт/www
.
Значения переменных окружения можно посмотреть с помощью программы на PHP, используя функцию phpinfo(), как показано в примере 2.
Пример 2. Использование phpinfo()
В результате выполнения программы будет выведена таблица с разными параметрами, в том числе и переменными окружения в разделе «Apache Environment» (рис. 1).
Рис. 1. Apache Environment
Также можно написать программу на PHP, которая будет выводить все переменные окружения в виде таблицы (пример 3)..
Пример 3. Вывод переменных окружения
\n\n
\n\n";
print "\n";
foreach ($_SERVER as $a => $b) print "$a | $b |
\n";
print "
\n";
print "\n\n";
?>
Переменные окружения, используемые в конфигурации, являются на сегодняшний день основным методом установки в приложении таких настроек, как учетные данные базы, 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 , который позволяет управлять вашими переменными окружения из одного места, не возясь с файлами самостоятельно, мне нравится такой подход, т. к. это гораздо проще!
Непосредственно перед запуском сценария сервер передает ему некие переменные окружения с информацией. В определенных переменных содержаться некоторые заголовки, но не все (получить все заголовки нельзя). Далее я приведу список наиболее важных переменных окружения.
HTTP_ACCEPT
В этой переменной перечислены все MIME-типы данных
, которые могут быть восприняты браузером. Строка */* означает, что браузер понимает любой тип.
HTTP_ACCEPT= image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*
HTTP_REFERER
Эта переменная представляет сведения о странице, с которой пользователь попал на данную. Эту переменную можно использовать, например, для отслеживания перемещения пользователя по вашему сайту, а затем просматривать наиболее популярные маршруты.
HTTP_REFERER= http://www.сайт/php/pril/
HTTP_COOKIE
В этой переменной хранятся все Cookies в URL-кодировке.
HTTP_COOKIE= hotlog=1; ZDEDebuggerPresent=php,phtml,php3; b=b; PHPSESSID=
HTTP_USER_AGENT
Идентифицирует браузер пользователя. Для установления типа браузера нужно проверить эту строку на наличие слов: если браузер - Internet Explorer, то будет присутствовать подстрока MSIE, а если в наличии лишь слово Mozilla, то это Netscape.
Например:
HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MyIE2; Maxthon)
HTTP_HOST
Содержит доменное имя Web-сервера, на котором запустился сценарий. Эту переменную достаточно удобно использовать, например, для генерации полного пути, который требуется в заголовке Location, чтобы не привязываться к конкретному серверу.
HTTP_HOST= www.сайт
HTTP_FROM
Адрес электронной почты пользователя, направившего запрос.
SERVER_NAME
Доменное имя или IP-адрес сервера.
SERVER_NAME= www.сайт
SERVER_SOFTWARE
Имя и версия программы-сервера, отвечающей на запрос клиента.
SERVER_PORT
Эта переменная содержит порт сервера, к которому обратился браузер пользователя. Обычно это 80. Переменная так-же может применяться для формирования параметра заголовка Location.
SERVER_PORT= 80
SERVER_PROTOCOL
Переменная содержит имя и версию информационного протокола, который был использован для запроса.
SERVER_PROTOCOL= HTTP/1.1
REMOTE_ADDR
Эта переменная содержит IP-адрес (или доменное имя) узла пользователя, на котором был запущен браузер.
REMOTE_PORT
Порт, который закрепляется за браузером пользователя для получения ответа сервера.
REMOTE_USER
Идентификационное имя пользователя, посылающего запрос.
SCRIPT_NAME
Содержит имя файла, содержащего данный сценарий. Эту переменную удобно использовать при формировании заголовка Location при переадресации на себя (self-redirect), а также для подставления значения атрибута action тега