Давайте сначала решим зачем нам может понадобиться запускать скрипты PHP через интерфейс командной строки Linux. Первое и самое очевидное решение, мы пишем простой скрипт который должен делать нечто в нашей системе. То есть мы используем PHP как расширенный Bush-скриптинг. Хотим как-то особенно сортировать файлы, делать запись в базу данных, отправлять сообщения или все одновременно. PHP позволяет реализовать это с легкостью. Повесим скрипт в Crone и вот полноценное системное приложение, несущее полезную нагрузку.
Минусов у такого подхода вагон. Из очевидных это ограничение по времени выполнения и ресурсам сервера. Но рано или поздно любой разработчик на PHP сталкивается с такой необходимостью. И знать как работает PHP в том числе и в консоли хоть и не строго обязательно, но лишним точно не будет.
Итак приступая к работе нужно понимать, что вы можете запустить любой скрипт PHP простой командой: php ../puth/index.php
. Это не совсем правильная команда, она чаще всего сработает, но вот что нужно понимать: вы запускаете скрипт с версией PHP по умолчанию, ваш интерпретатор может не поддерживать такой запуск. Попробуйте так сделать и посмотрите что будет выведено в консоль. Мой PHP-FPM 7.4 выдал исходный код скрипта мне прямо в консоль. А вот на другом сервере я получил ошибку. Хотя версия установлена идентичная. Все дело в том, что на втором сервере установлено сразу две версии интерпретатора языка и версия по умолчанию просто не запущена. Я не стал разбираться как такое может быть, просто указал конкретный интерпретатор /usr/bin/php7.4 /var/site.ru/script.php
.
Есть еще одна особенность. Если вызвать скрипт /usr/bin/php /var/site.ru/script.php
, находясь в другой директории, можно получить ошибку доступа. У меня создается файл log.txt и строчка вызова fopen("log.txt", "w");
выдавала ошибку, пока я не «вошел» в консоли в директорию со скриптом запуска. Но когда добавил версию интерпретатора, вызов начал работать как надо.
Вы можете проверить какие версии бинарниуков есть в вашей системе, просто взглянув на содержимое директории /usr/bin/. Если в папке присутствует несколько версий, тогда просто укажите при запуске ту, которая работает по умолчанию. Проверить версию по умолчанию: php -v
.
Я запускаю скрипт и получаю в консоль весь исходный код. У меня подразумевался вывод echo и я хотел получать результаты работы скрипта, но судя по логу, который я предусмотрительно решил записывать в файл, скрипт отработал как положено. То есть, осталось решить вопрос с выводом результата.
Тут как всегда несколько путей. Первый, самый простой как пуля в лоб. Будем писать весь вывод в космос на «пустое устройство», добавив в конец строки: > /dev/null
. Но в пустоту будет отправлен не весь вывод, а только стандартный. Мы все же получим поток ошибок, если в него что-то поступит. Вот только ошибки PHP7 это часть стандартного потока, а ждать системных ошибок от работы интерпретатора это как носить зонт в солнечный день.
Еще одна проблема подхода «в лоб» в том, что мы запускаем «однофайловый» скрипт. Если в нем будет require то получим ошибку. Интерпретатор сообщит, что не шарит в пространстве имен и не может подключить файл. Можно захардкодить путь к директории от корня сервера, можно добавить константу: $_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__).'/../..');
, это может сработать, да. Но может и не сработать. Если вы еще не поняли, многое зависит от конфигурации php, версии и установки.
Если все работает и так, можно немного расширить наш вывод /usr/bin/php7.4 /var/site.ru/script.php > /dev/null & echo $!
, в таком случае будем получать ошибки и предупреждения, а так же вывод echo из самого PHP скрипта.
Когда вы получаете ошибку связанную с конфигурацией PHP, например, скрипт требует параметры которые вы по каким-то причинам не желаете включать в php.ini можно вызвать скрипт с этими параметрами. Дам часто используемый пример:
/usr/bin/php7.4 -d display_errors -d short_open_tag /var/site.ru/script.php
Здесь мы подключили модуль вывода ошибок display_errors и short_open_tag, вместо того, чтобы включать их в php.ini. Это удобно, если параметры не требуются для работы остальных скриптов или не рекомендованы с точки зрения безопасности, а вам они полезны.
Как видите, мы указываем директивы PHP при помощи опции -d (—define). Опций существует большое количество и узнать о них можно в официальной документации. Можно так же получить всю информацию по опциям, запросив их через /usr/bin/php7.4 --help
.
Чтобы полноценно работать с консолью в PHP существует пакет php-cli
. Установив его sudo apt-get install php-cli7.4
, получаем куда больше возможностей. Первая возможность, о которой следует помнить это то, что теперь для php который мы будем использовать в консоли есть свой php.ini.
Настроить его можно sudo vim /etc/php/7.4/cli/php.ini
. Вы можете внести все необходимые настройки. Например, можно увеличить лимиты для скриптов запускаемых из консоли или установить какие-то небезопасные параметры, которые будут использоваться только через php-cli.
Таким образом, мы можем получить некий аналог Bush только с ООП.
А что на счет консольных приложений? Имеются в виду полноценные консольные приложения на PHP. Оказывается, мы можем пойти еще дальше и написать полноценное консольное приложение используя CLI SAPI. Собственно, его мы и использовали, указывая директивы.