- Как добавить путь до PHP в переменную окружения PATH в Windows
- Что такое и для чего нужна PATH
- Нужно ли в Windows добавлять PHP в переменную окружения
- Как добавить PHP в системные переменные среды
- Установка PHP 7.1 в Windows. Командная строка
- Загружаем PHP для Windows
- Устанавливаем PHP 7.1
- Подключаем конфигурационный файл
- Тестируем PHP из командной строки
- Упрощаем обращение к php.exe
- Еще немного о переменных окружения
- PHP Profi
- Квест → Как хакнуть форму
- Всё, что вы должны знать о переменных окружения в PHP Перевод
- Env vars 101
- Лучшие практики на сегодня
- Я читал(а) в Интернете, что переменные окружения опасны
- Подготовка приложения
- Библиотеки «Dot Env» в помощь
- vlucas/phpdotenv, самая популярная библиотека на данный момент:
- josegonzalez/dotenv, ориентирована на безопасность:
- symfony/dotenv, новый малыш на этом поприще:
- Подводные камни, на которые вы должны обратить внимание ⚠
- Конфликты имен
- Отсутствие переменных во время выполнения
- Префикс HTTP_
- Потокобезопасность функции getenv()
- Переменные окружения – всегда строки
- Переменные окружения везде или нет
Как добавить путь до PHP в переменную окружения PATH в Windows
Что такое и для чего нужна PATH
Вполне возможно, что вам не приходилось ранее сталкиваться с PATH и выражениями «переменная окружения», поэтому я кратко поясню, что это такое.
Переменная PATH содержит список папок, в которых Windows ищет исполнимые файлы.
В графическом интерфейсе, когда для запуска программ используются ярлыки, значение PATH не очень большое. Но если вы запускаете программу в командной строке, то PATH может пригодиться. Опять же, если вы указываете полный путь до файла, например, C:\Users\Alex\Documents\php.exe, то PATH не используется. Но если, например, вы запускаете программу только по имени файла или просто по имени (без файлового расширения), то запустится ли программа, будет зависеть от содержимого переменной PATH.
К примеру, я в командной строке пытаюсь запустить файл (без указания полного пути)
В этом случае операционная система посмотрит все записи PATH (там может быть указано несколько каталогов). Затем в каждом из этих каталогов Windows попытается найти файл php.exe. Если файл найден, то он будет запущен. Если файл не найден, то будет выведено соответствующее сообщение.
По сути, что-то дописывать в переменную PATH нужно только тем, кто много работает с командной строкой. К примеру, вы программист и размещаете свои программы в папке C:\MyApps и при этом вы часто запускаете свои утилиты командной строки. В этом случае вы можете добавить C:\MyApps в PATH и после этого для запуска программ из этой папки вам уже не нужно будет каждый раз вводить полное имя (например, C:\MyApps\parser.exe), а достаточно будет в командной строке ввести только имя файла:
Нужно ли в Windows добавлять PHP в переменную окружения
При установке и настройке PHP в Windows необязательно добавлять в PATH путь до PHP, но это рекомендуется делать.
Во-первых, вы сможете запускать PHP используя сокращённую запись:
Во-вторых, ряд расширений (которые включаются в файле php.ini) работают некорректно, если вы не прописали в PATH путь до PHP; в том числе, это касается такого довольно популярного расширения как cURL. По идее — это какой-то баг этих расширений или PHP, но нам самим придётся исправлять ситуацию, поскольку эта проблема существует уже много лет.
Как добавить PHP в системные переменные среды
Нажмите кнопку Windows (это которая раньше была кнопкой «Пуск»), начните набирать «Изменение системных переменных среды»
и откройте соответствующее окно настроек.
Там нажмите «Переменные среды», откроется:
В окне «Системные переменные» найдите и кликните на Path, потом нажмите «Изменить»:
Далее «Создать» и впишите туда «C:\Server\bin\PHP\»:
Поднимите запись в самый Вверх:
Закройте все окна с сохранением сделанных изменений.
Установка PHP 7.1 в Windows. Командная строка
В htmlAcademy стартовал первый базовый интенсив по PHP и я работаю на нем наставником. Студентам в рамках интенсива предстоит поднять рабочее окружение и это заметка нацелена упростить эту нелегкую для новичка задачу. Есть разные способы поднятия полноценного LAMP стека, но мы пойдем классическим путем. Настроим все компоненты по отдельности (без применения готовых комбайнов) и начнем с PHP (обязательно будет заметка с рассмотрением готовых сборок LAMP). Поскольку я планирую работать наставникам на интесивах по PHP и дальше, я собираюсь написать подобные инструкции для повторения в других ОС (Linux, macOS). Как говорится, лучше один раз попотеть, но потом всем станет проще. Итак, приступаем.
Загружаем PHP для Windows
Заходим на официальный сайт и загружаем актуальную версию PHP. На момент написания заметки это – 7.1.4. На странице доступно несколько вариантов дистрибутивов. У меня Windows 7 x64, соответственно я выбираю zip архив с VC14 x64 Thread Safe.
Обратите внимание, для загрузки доступна два варианта дистрибутива: Thread-Safe (TS) и Non-Thread-Safe (NTS). Выбор зависит от того как вы планируете применять интерпретатор. TS рекомендуется использовать для одного процесса веб-служб (например, настраивая через модуль mod_php для Apache). NTS рекомендуется для применения IIS (Internet Information Service) и альтернативных FastCGI веб-сервером (например, Apache с модулем FastCGI) и командной строки.
Устанавливаем PHP 7.1
Начнем готовить PHP для комфортной работе из командной строки. В предыдущем шаге вы загрузили архив с дистрибутивом PHP. В отличие от большинства программ, PHP поставляется в простом архиве, а не как инсталляционный пакет. Поэтому вам придется самостоятельно извлечь файлы в любую удобную для вас директорию. Я предпочитаю хранить подобные вещи в корне системного диска. Создайте в корне диска «C:» (или любом другом месте) директорию «php» и извлеките в нее содержимое загруженного архива.
В директории появится множество файлов, но нас больше всего интересуют:
- go-pear.bat – сценарий для установки PEAR. Подробности о PEAR можно почитать в официальной документации.
- php.exe – позволяет выполнять PHP сценарии из консоли;
- php-win.exe — позволяет выполнять PHP сценарии без применения консоли;
- php-cgi.exe – необходим для выполнения PHP кода в режиме FastCGI;
- php7apache2_4.dll – модуль интеграции с веб-сервером Apache 2.4.X;
- phpdbg.exe – отладчик;
- php.ini-development – пример конфигурационного файла PHP для окружения разработчика (development)
- php.ini-production – пример конфигурационного файла PHP для рабочего окружения (production)
Подключаем конфигурационный файл
Распакованный дистрибутив у нас есть, подключим для него конфигурационный файл. Мы собираемся ставить эксперименты, поэтому в качестве образца возьмем php.ini-development. Сделайте копию этого файла в директорию php (C:\php) с именем php.ini. ВАЖНО! Делайте именно копию, не простое переименование. За время разработки вам может потребоваться изменять конфигурационный файл и есть все шансы совершить ошибку, которую трудно будет обнаружить.
В таких случаях нет ничего лучше, чем вернуться к эталонным настройкам. В нашем случае будет достаточно повторить копирование файла php.ini-development в php.ini. Итак, по окончанию телодвижений в директории с php должен появиться файлик php.ini. В дальнейших заметках мы обязательно поговорим о его содержимом более детально.
Тестируем PHP из командной строки
На этом шаге, так называемая «установка» завершена. Откройте консоль (cmd.exe, ярлык доступен в меню «Стандартные») и введите команду:
Результат будет примерно таким:
Результат подтверждает, что PHP работает. Попробуйте для примера создать новый файл-сценарий (я создал файл “test.php” прямо в корне диска “C:”) и поместить в него текст:
Теперь попробуйте выполнить этот файл и посмотрите результат:
Функция phpinfo() выводит информацию по конфигурации PHP в удобном виде. Об этой функции мы еще поговорим.
Упрощаем обращение к php.exe
PHP готов к работе, но согласитесь, каждый раз вбивать в консоле путь к php интерпретатору довольно неудобно. Чтобы упростить себе жизнь, внесем небольшие изменения в переменные среды. Запустим в панели управления аплет «Система» (или просто нажмем горячую клавишу «Windows + Pause Break». Затем нажмем на кнопку «Изменить параметры». В появившемся окне «Свойства системы», перейдем на закладку «Дополнительно». Найдите и нажмите на ней кнопку «Переменные среды».
Находим в списке переменную «PATH» и нажимаем кнопку «Изменить», появится окно редактирования переменной. В поле «Значение переменной» нам необходимо дописать путь к директории с PHP. Перейдите в самый конец строки и через точку с запятой укажите путь к директории с PHP: C:\php;
Все, нажимайте «Ok». Теперь перезагрузите систему (увы, придется). После перезагрузки Windows, обращаться к PHP можно будет просто: php.Например, чтобы вывести название версии достаточно написать:
А чтобы интерпретировать файл test.php, расположенный в корне диска «C:»:
Или вовсе запустить встроенный веб-сервер:
Для тестирования откройте web-браузер попробуйте обратиться на http://127.0.0.1:8888/test.php. Обратите внимание, после параметра –t мы указываем путь к директории, которая станет корневой директорией веб-сервера. Все сценарии, расположенные в этой папке будут доступны для запроса с клиента. У меня на диске «C:» есть один файлик 1.php и именно его я и запрашиваю.
Можно пойти немного дальше и ассоциировать расширение .php с интерпретатором, т.е. сделать все файлы с расширением php исполняемым по умолчанию. Для этого вводим в консоле несколько команд:
Еще немного о переменных окружения
Теперь давайте поговорим о том как PHP будет искать файл настроек конфигурации (вспоминаем, о php.ini). В документации приведена полная цепочка поиска. Во избежание лишних сложностей, рекомендую сразу добавить в переменные окружения новую – «PHPRC» и в качестве значения указать путь к директории с конфигурационным файлом. У меня конфиг располагается в тоже же директории, что и основные файлы php, следовательно в качестве значения переменной указываю –
«C:\php». После внесения изменения потребуется перезагрузка.
На этом у меня все. Первый часть мануала для новичков готова.
PHP Profi
Квест → Как хакнуть форму
Всё, что вы должны знать о переменных окружения в PHP Перевод
Переменные окружения, используемые в конфигурации, являются на сегодняшний день основным методом установки в приложении таких настроек, как учетные данные базы, API ключи, секретные ключи и всего, что является различным в зависимости от того, где развертывается приложение. Сейчас такие настройки попадают в код через окружение, вместо прямого прописывания в файлах конфигурации или, того хуже, хардкода прямо в коде.
Давайте подробнее взглянем на то:
- как это работает?
- действительно ли это хорошая идея?
- как с ними работать в PHP?
- и в заключение на некоторые рекомендации и распространенные ошибки, которых следует избегать – на те ловушки, на которые мы наткнулись в реальном мире!
Мы не будем рассматривать как настроить переменные окружения в вашем веб-сервере / Docker-е / crontab-ах. т. к. это зависит от системы, программного обеспечения, а мы хотим сосредоточиться на самих переменных окружения.
Если ваш хостинг использует Docker Swarm или AWS, все будет немного по-другому, например, т. к. они решили подсовывать файлы на файловую систему вашего контейнера, чтобы внедрить ваши секретные ключи, а не использовать переменные окружения. Это очень специфично для этих платформ и не является распространённым вариантом для всех.
Env vars 101
При запуске программы, она наследует все переменные окружения от своих родителей. Так что если вы установите переменную YOLO в значение covfefe в bash, а затем выполните команду, вы сможете прочитать YOLO в любом дочернем процессе.
Поскольку эта переменная определена только локально, мы не можем прочитать её из другого терминала (другого родителя). Идея в том, чтобы убедиться, что ваше приложение всегда наследует нужные переменные.
Вы можете посмотреть все переменные окружения в командной строке, выполнив следующую команду, но вы не увидите переменной YOLO , т. к. она была передана только в команду php «на лету», а не установлена в текущем процессе:
Вы можете установить переменную окружения с помощью export = :
Имена переменных чувствительны к регистру и соглашение заключается в использовании имён только на английском, в верхнем регистре, с _ в качестве разделителя (т. н. «змеиный» стиль в верхнем регистре). Вы уже наверняка знаете некоторые переменные – такие как PATH , DISPLAY , HTTP_PROXY …
Лучшие практики на сегодня
Возможно, вы уже знаете о двенадцати факторной методологии для создания надежных и масштабируемых приложений (если нет, то я предлагаю вам сделать перерыв и проверить его). Глава о конфигурации объясняет, почему сохранение конфигов в окружении это правильный путь:
- Конфигурация существенно отличается в зависимости от того, где развёрнуто приложение (production, staging, testing…), код – нет.
- Переменные окружения легко изменять на разных машинах без изменения кода.
- Они являются стандартом и не зависят от используемого язык или ОС. Одни и же конфигурации могут использоваться и PHP, и Python процессами.
Манифест также довольно хорошо описывает что должно быть в коде и что должно быть в окружении – не кладите все настройки приложения в него, только то, что отличается у одного развернутого стенда от другого.
Я читал(а) в Интернете, что переменные окружения опасны
Некоторые статьи расскажут вам, что переменные окружения вредны для ваших секретных ключей. Главная причина заключается в том, что любой процесс наследует от своего родителя переменные, все из них. Так что если у вас очень секретная настройка в окружающей среде, дочерние процессы будут иметь доступ к нему:
Дочерние процессы могут рассматривать переменную окружения, как что-то публичное, что можно записать в логи, включить в отчеты об ошибках, вывести пользователю в случае ошибки. Они могут допустить утечку ваших секретных ключей.
Альтернатива – старые текстовые файлы, со строгими Unix-правами. Но что действительно должно быть сделано, очистка окружения при запуске дочернего процесса, которому вы не доверяете, как это делает nginx. По умолчанию nginx удаляет все переменные окружения, унаследованные от своего родительского процесса, за исключением переменной TZ. Проблема решена!
Это можно сделать с помощью команды env -i , которая говорит, что следующие команды должны быть запущены в пустой среде.
Всегда запускайте процессы, которым вы не доверяете, в ограниченной среде.
Даже если вы доверяете вашему коду, вы всё равно должны быть очень осторожны и передавать ваши переменные как можно меньшему количеству процессов – кто и как их будет использовать вы никогда не знаете (внутри драма в NPM-проекте).
Подготовка приложения
При работе с переменными окружения в PHP-проекте, вы хотите убедиться, что ваш код всегда будет получать переменную из надежного источника, будь то $_ENV , $_SERVER , getenv . Но эти три метода не возвращают одинаковые результаты!
Это потому что настройка variables_order в PHP на моей машине установлена в «GPCS» . И так как в ней нет буквы «E» , я не могу полагаться на суперглобальный массив $_ENV . Это может привести к тому, что код работающий на одном PHP не будет работать на другом.
Другой камень преткновения – это то, что разработчики не хотят управлять переменными окружения локально. Каждый раз, когда мы редактируем VirtualHost, мы не хотим перезагружать php-fpm или некую службу, или очищать кеш. Разработчики хотят иметь простой и безболезненный способ настройки переменных окружения. как .env файл!
Файл .env — это просто сборник переменных окружения с их значениями:
Библиотеки «Dot Env» в помощь
vlucas/phpdotenv, самая популярная библиотека на данный момент:
Эта библиотека будет читать .env файл и заполнит все суперглобальные переменные:
Есть несколько хороших плюшек, таких как возможность помечать некоторые переменные, как обязательные. (используется фреймворком Laravel)
josegonzalez/dotenv, ориентирована на безопасность:
Эта библиотека не заполнит суперглобальные переменные по умолчанию:
Она поддерживает обязательные переменные, фильтрацию, и может выбрасывать исключения, когда переменная перезаписывается.
symfony/dotenv, новый малыш на этом поприще:
Доступен начиная с Symfony 3.3. Этот компонент заботится о .env -файле, как остальные, и тоже заполняет суперглобальные массивы:
На packagist есть ещё куча других и я даже боюсь спрашивать, почему каждый пишет тот же парсер снова и снова.
Но все они используют ту же логику:
- найти .env файл;
- разобрать его, проверить на вложенные значения, вытащить все переменные;
- заполнить все суперглобальные массивы переменными, кроме тех, что уже установленны.
Я рекомендую комитить файл .env со значениями, заданными для разработчиков: каждый должен иметь возможность вытащить ваш проект и запустить его так, как ему нравится (сервер из командной строки, Apache, nginx. ) без мучений с конфигурацией.
Эта рекомендация хорошо работает, когда каждый локально имеет ту же инфраструктуру: тот же пароль к БД, тот же сервер и порт. Т. к. мы используем Docker Compose на всех наших проектах, у нас никогда нет никаких различий в настройках одного разработчика от настроек другого. Если у вас нет такой плюшки, просто позвольте разработчикам перезаписывать настройки по умолчанию, импортировав два файла:
В этом случае, вы просто должны создать и заполнить файл .env.dev тем, что отличается для вас (и добавить его .gitignore ).
Затем на продакшене, вы не должны загружать эти значения по умолчанию:
Если вы так не сделаете, и ваш хостинг-провайдер забудет передать переменную, то запустите код в продакшене с настройками от дева, а это не приведёт ни к чему хорошему.
Подводные камни, на которые вы должны обратить внимание ⚠
Конфликты имен
Нейминг – это сложно, и переменные окружения не являются исключением из этого правила.
Поэтому при именовании переменных окружения, вы должны быть осторожными и допускать как можно меньше конфликтов имен. Ситуация усложняется тем, что нет официального списка зарезервированных имен. Хорошая практика – использовать префиксы пользовательских переменных.
В мире Unix это уже делают, используя LC_ , GTK_ , NODE_ …
Отсутствие переменных во время выполнения
У вас есть два варианта в случае, если переменная отсутствует: либо бросить исключение, или использовать значение по умолчанию. Решать вам, но второй вариант молчаливый. Что может принести вред во многих случаях.
Как только вы захотите использовать переменные окружения, вы должны установить их везде:
- на веб-сервере;
- в длительных скриптах и сервисах;
- в crontab-ах…
- и в сценарии развертывания!
Про последний легко забыть, но так как сценарии могут разогревать кеш приложения (как Symfony-вские). да, отсутствие переменной может привести к поломке деплоя. Будьте осторожны с этим и добавите проверку при запуске приложения.
Префикс HTTP_
Есть только один префикс, который вы никогда не должны использовать: HTTP_ . Потому что его использует сам PHP (и другие cgi-подобные контексты) для хранения заголовков http-запроса.
Вы помните httpoxy уязвимость? Она возникала при поиске http-клиентом переменной в окружении таким образом, что её можно было установить через простой http-заголовок.
Некоторые DotEnv-библиотеки также предотвращают переопределение таких переменных, например, Symfony-компонент.
Потокобезопасность функции getenv()
У меня плохие новости: в некоторых конфигурациях, использование функции getenv() приведет к неожиданным результатам. Эта функция не потокобезопасна!
Вы не должны использовать её для получения ваших значений, поэтому я предлагаю вам вместо этого обращаться к $_SERVER – к тому же есть небольшая разница в производительности между обращением к массиву и вызовом функции в пользу массивов.
Переменные окружения – всегда строки
Одной из главных проблем является то, что сейчас в PHP есть указание типов, а наши настройки не всегда правильно набраны.
В Symfony теперь можно преобразовывать variables, а даже больше – чтение файла, декодирование json. …
Переменные окружения везде или нет
На данный момент существует много споров между использованием переменных окружения, файлов, или их смеси: переменная окружения ссылается на файл конфигурации. Дело в том, что несмотря на то, что это считается лучшей практикой, переменные окружения не представляют больших преимуществ.
Но если правильно использовать, в приложении на Symfony, например, переменные окружения могут быть изменены «на лету» — без очистки какого-либо кеша, без обращения к файловой системе, без развертывания кода: просто перезапустив процесс, например.