Как запустить php в консоли
Этот раздел содержит примечания и подсказки, относящиеся к запуску PHP из командной строки для Windows.
Запуск PHP из командной строки можно выполнить без внесения каких-либо изменений в Windows.
C:\php\php.exe -f "C:\PHP Scripts\script.php" -- -arg1 -arg2 -arg3
Но есть несколько шагов, которые помогут упростить этот процесс. Некоторые из этих шагов уже должны были быть предприняты, но они повторяются здесь, чтобы иметь возможность предоставить полную пошаговую последовательность.
Замечание:
И PATH , и PATHEXT являются важными переменными, изначально существовавшими в Windows, и следует позаботиться о том, чтобы не перезаписывать ни одну из переменных, а только добавлять к ним.
Замечание: Позиция, в которую вы помещаете .PHP , будет определять, какой скрипт или программа будет выполняться при совпадении имён файлов. Например, размещение .PHP перед .BAT приведёт к запуску вашего скрипта, а не пакетного файла, если существует пакетный файл с тем же именем.
assoc .php=phpfile
ftype phpfile="C:\php\php.exe" -f "%1" -- %~2
Выполнение этих шагов позволит запускать скрипты PHP из любого каталога без необходимости вводить исполняемый файл PHP или расширение .PHP , и все параметры будут переданы скрипту для обработки.
В приведённом ниже примере описаны подробности о некоторых изменениях в реестре, которые можно сделать вручную.
Пример #1 Изменения в реестре
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.php] @="phpfile" "Content Type"="application/php" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile] @="PHP Script" "EditFlags"=dword:00000000 "BrowserFlags"=dword:00000008 "AlwaysShowExt"="" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\DefaultIcon] @="C:\\php\\php-win.exe,0" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell] @="Open" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open] @="&Open" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open\command] @="\"C:\\php\\php.exe\" -f \"%1\" -- %~2"
С этими изменениями эту же команду можно записать как:
"C:\PHP Scripts\script" -arg1 -arg2 -arg3
или, если ваш путь «C:\PHP Scripts» находится в переменной окружения PATH :
script -arg1 -arg2 -arg3
Замечание:
Есть небольшая проблема, если вы собираетесь использовать эту технику и использовать свои скрипты PHP в качестве фильтра командной строки, как в примере ниже:
dir | "C:\PHP Scripts\script" -arg1 -arg2 -arg3
dir | script -arg1 -arg2 -arg3
Вы можете обнаружить, что сценарий просто зависает и ничего не выводится. Чтобы это заработало, необходимо внести ещё одно изменение в реестр.
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer] "InheritConsoleHandles"=dword:00000001
Дополнительную информацию по этой проблеме можно найти в этой » статье базы знаний Microsoft : 321788. В Windows 10 этот параметр изменён на противоположный, и стандартная установка Windows 10 поддерживает унаследованные дескрипторы консоли. Это » сообщение на форуме Microsoft предоставляет объяснение.
Как запустить PHP-скрипт из SSH-консоли, чтобы он работал после закрытия вкладки?
Написал скрипт, разместил файлик на хостинге, исполнил в консоли команду:
php adress/bot/index.php — работает только, пока вкладка открытая.
Прогуглил команду nohup с ключом & исполнил такие команды:
nohup php adress/bot/index.php &
nohup php adress/bot/index.php > /dev/null &
Но все они перестают работать при закрытии вкладки с консолью. Что-то так себе бот выходит 🙂
Как запустить демона, чтобы он работал всегда?
Command Line Interface в PHP
До этого момента мы с Вами знали, что PHP работает на сервере. Клиент обращается к серверу по протоколу HTTP с каким-либо запросом, запрос на сервере обрабатывается и формируется ответ. После этого клиенту снова по протоколу HTTP в ответе отдаётся сформированный ответ. Однако, если взять какой-нибудь более-менее продвинутый сайт, то мы увидим, что есть задачи, которые не решаются стандартным клиент-серверным путем. Например: поздравлять пользователей с днём рождения и дарить им скидку на какой-нибудь продукт. Для того, чтобы это сделать, нам придется обновлять раз в день php-скрипт в браузере, чтобы он выбирал пользователей, у которых сегодня ДР, затем создавал для них скидки, и отправлял им сообщения по почте. Согласитесь, неудобно это делать вручную и в браузере. Для таких случаев в PHP предусмотрен Command Line Interface (CLI) – интерфейс командной строки.
CLI позволяет запускать программы на PHP не через привычную нам клиент-серверную архитектуру, а как простые программы в командной строке. Давайте создадим простейший скрипт, чтобы показать, как это работает. Создаём новую папку bin в корне проекта, а в ней файл – cli.php.
Пишем простейший код:

А теперь запускаем консоль из OpenServer:
Переходим в папку с нашим проектом, выполнив:
cd domains\myproject.loc
И пишем следующую команду:
php bin/cli.php

В ответ получаем:
Написали простейшее консольное приложение! Уже неплохо. Но что если мы захотим сложить 2 числа, которые нужно передать скрипту? Как Вы понимаете, сделать это с помощью GET- или POST- запросов уже не получится. Так как же быть?
Аргументы консольного приложения

На помощь нам приходят аргументы, которые мы можем передать в скрипт, указав их после имени скрипта в командной строке. Вот так:
А для того, чтобы получить к ним доступ из php-скрипта используется магическая переменная $argv. Она представляет собой массив, в котором нулевой элемент – это путь до скрипта, а все последующие – это его аргументы в консоли.

Давайте теперь запустим наш скрипт с параметрами:
Как видим, наши аргументы попали в этот массив. Давайте напишем простейший скрипт, который будет складывать все переданные ему аргументы.
echo $sum;

Запустим его, и убедимся, что все работает:
И он действительно работает: 3 + 4 + 5 = 12.

А что если мы хотим передавать аргументы с именами? Вроде такого:
И затем в коде получать их в коде по их именам? Для этого нам следует написать простейший парсер, который будет находить вот такие именованные параметры и их значения. Пишем.
> var_dump($params);

И проверяем его работу:
Отлично, теперь мы можем обращаться к элементам массива params, чтобы выяснить, были ли нам переданы какие-то аргументы или нет.
CLI и ООП
Мы с вами изучили некоторые основы работы с CLI. Давайте теперь перенесем эти знания на объектно-ориентированный подход и научимся работать через интерфейс командной строки с объектами.

Для этого нам понадобится создать отдельную директорию под «команды». Команды – так мы будем называть наши специальные классы, которые будут выполнять какой-то код через запуск из командной строки. Создаем новую директорию: src/MyProject/Cli.
И теперь создадим наш первый класс, который будет заниматься тем, что считает сумму переданных в него аргументов: -a и -b.
params = $params; $this->checkParams(); > public function execute() < echo $this->getParam('a') + $this->getParam('b'); > private function checkParams() < $this->ensureParamExists('a'); $this->ensureParamExists('b'); > private function getParam(string $paramName) < return $this->params[$paramName] ?? null; > private function ensureParamExists(string $paramName) < if (!isset($this->params[$paramName])) < throw new CliException('Param with name "' . $paramName . '" is not set!'); >> >
В конструкторе класса мы принимаем список параметров, сохраняем их, а затем вызываем метод checkParams(), который проверяет наличие обязательных параметров для этого скрипта. В нём просто поочередно вызывается метод для проверки в массиве нужных ключей. Если их нет – метод кинет исключение. И, наконец, есть метод execute(), который содержит бизнес-логику. В нем используется метод getParam(), который вернет параметр (при его наличии), либо вернет null (при его отсутствии).
И также создаём исключение, специально для ошибок, возникающих при работе с CLI.
Теперь давайте снова вернемся в нашу точку входа для консольных приложений cli.php. Этот файл можно назвать фронт-контроллером для консольных команд, он как index.php в случае с клиент-серверным подходом будет создавать другие объекты и запускать весь процесс.
Дополним этот код так, чтобы он создавал экземпляр нужного класса и передавал ему аргументы.
); // Составляем полное имя класса, добавив нэймспейс $className = '\\MyProject\\Cli\\' . array_shift($argv); if (!class_exists($className)) < throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not found'); >// Подготавливаем список аргументов $params = []; foreach ($argv as $argument) < preg_match('/^-(.+)=(.+)$/', $argument, $matches); if (!empty($matches)) < $paramName = $matches[1]; $paramValue = $matches[2]; $params[$paramName] = $paramValue; >> // Создаём экземпляр класса, передав параметры и вызываем метод execute() $class = new $className($params); $class->execute(); > catch (\MyProject\Exceptions\CliException $e) < echo 'Error: ' . $e->getMessage(); >

Теперь мы можем запустить наш скрипт с помощью вот такой команды:
Если мы захотим создать еще один класс, в котором мы будем вычитать из аргумента a аргумент b, то нам нужно будет продублировать довольно большой объем кода. Но ведь если присмотреться – большую часть кода из класса Summator можно вынести в отдельный класс и использовать его повторно.
Давайте создадим абстрактный класс, который будет заниматься тем, что будет сохранять переданные в него параметры и запускать метод для их проверки.
params = $params; $this->checkParams(); > abstract public function execute(); abstract protected function checkParams(); protected function getParam(string $paramName) < return $this->params[$paramName] ?? null; > protected function ensureParamExists(string $paramName) < if (!isset($this->params[$paramName])) < throw new CliException('Param with name "' . $paramName . '" is not set!'); >> >
Теперь нам в классе Summator достаточно отнаследоваться от этого класса и он значительно упростится:
ensureParamExists('a'); $this->ensureParamExists('b'); > public function execute() < echo $this->getParam('a') + $this->getParam('b'); > >

Запустим скрипт снова и убедимся, что все успешно отработало:
Давайте создадим по аналогии скрипт, который будет вычитать из аргумента x аргумент y.
ensureParamExists('x'); $this->ensureParamExists('y'); > public function execute() < echo $this->getParam('x') - $this->getParam('y'); > >

Проверим его в деле:

А теперь давайте попробуем не указать один из аргументов – получим ошибку.
Вот таким вот нехитрым образом мы с вами научились создавать простейшие программы для запуска в консоли на PHP. А в следующем уроке мы с вами научимся запускать эти команды по расписанию.
