CMS.CLI: Утилиты командной строки
Зачастую при разработке сайтов необходимо применять PHP-скрипты, запускаемые из командной строки вручную или посредством cron. Это могут быть скрипты для генерации файлов, свертки/подсчета статистики, рассылки уведомлений и т.п. Для этого в ТАО предусмотрен набор модулей CMS.CLI, который реализует простейший фреймворк для написания приложений с интерфейсом командной строки.
Основная идея заключается в том, чтобы не писать отдельный сценарий командной строки для запуска PHP-кода, а вместо этого реализовать единый универсальный сценарий запуска, принимающий в качестве параметра имя модуля, реализующего специальный интерфейс.
Как писать утилиты командной строки
Для создания своей утилиты достаточно в каталоге app/lib создать файл-модуль App.CLI.
// app/lib/CLI.php class App_CLI extends CMS_CLI_Handler implements Core_ModuleInterface { public function test() { // Тут какие-то действия } }
И вызвать метод test в командной строке. Если метода с таким именем нет, то ничего не произойдет.
php index.php <имя_действия> php index.php test
Разделение действий по модулям
Если скриптов с разными действиями много, то держать их все в одном файле не рационально. Для разделения достаточно создать каталог app/lib/CLI и разместить в нем несколько модулей с точно таким же форматом. Они все будут запущены. Причем в разных модулях App.CLI.* могут быть методы с одинаковыми именами.
Если в нескольких модулях, например, есть методы с именем test, то они все будут последовательно запущены.
Одноименные действия в разных компонентах
Модули можно создавать и для каждого компонента отдельно. Тогда модуль необходимо создать непосредственно в самом компоненте.
// app/components/Forum/CLI.php class Component_Forum_CLI extends CMS_CLI_Handler implements Core_ModuleInterface { public function daily() { // Рассылка ежедневного дайджеста } public function hourly() { // Рассылка ежечасных уведомлений } }
Тогда при вызове в командной строке поиск методов будет выполняться по следующим правилам:
- Если существует модуль App.CLI, то он будет загружен, и в нем будет вызван метод <имя действия> (если он есть).
- Если существует каталог app/lib/CLI, то будут последовательно загружены все модули App.CLI.* из этого каталога, и в каждом из них будет вызван метод <имя действия> (если он есть).
- Будут просмотрены все подключенные к проекту компоненты, в каждом из них будет загружен модуль Component.*.CLI (если есть), и в каждом из них будет вызван метод <имя действия> (если он есть).
Аргументы и опции
При написании утилит часто возникает потребность, чтобы скрипт запускался с дополнительными опциями. Например
php index.php image photo.jpg --quality=70 --grayscale
где
- photo.jpg - аргумент
- quality - опция с параметром
- grayscale - опция без параметра (принимает булево значение)
Получить доступ к переданным аргументам и опциям легко:
public function image() { print count($this->args); // сколько аргументов передано (опции не считаются) print $this->args[0]; // photo.jpg print $this->options['quality']; // 70 if ($this->options['grayscale']) print 'grayscale'; }
Конструкторы
При написании классов CLI приложений нужно осторожно обращаться с конструкторами. При выполнении любого консольного скрипта будут созданы экземпляры всех классов, находящихся в папке CLI, вне зависимости от того, есть ли в классе целевой метод или нет. А если скриптов много, то это может сильно повлиять на производительность.
Список готовых утилит
- tao_stockroom - утилита позволяет устанавливать, обновлять или удалять компоненты (параметры: install / update / delete).
php index.php tao_stockroom ComponentName install
- tao_s - укороченный вариант утилиты tao_stockroom.
php index.php tao_s ComponentName update
- tao_update - обновление версии ядра ТАО до текущей.
php index.php tao_update
- component_assets_dump - копирование содержимого папок app/components/CompName/images|file/... в www/components/CompName/.... Необходимо указать название компонента.
php index.php component_assets_dump CompName
- tao_clear_cache - очистка кэша. Есть возможность удалить кэш по ключу.
php index.php tao_clear_cache //удалить весь кэш php index.php tao_clear_cache [key] //удалить кэш по ключу
- tao_cache - операции с кэшем.
php index.php tao_cache get [key] [value] //получить значение по ключу кэша php index.php tao_cache set [key] [value] //установить значение по ключу php index.php tao_cache delete [key] [value] // удалить значение по ключу
- sqlc - подключение к текущему серверу баз данных.
php index.php sqlc
- sql_dump - создание резервной копии текущей базы данных.
php index.php sql_dump > /path/to/file/database.sql
- sql_query - сформировать и произвести запрос к текущей базе данных.
php index.php tao_query "select * from table_name"
cli_dispatcher
В CLI реализована возможность применить единый вызов всех cli-команд, не прибегая к прописыванию каждой в кроне. Для этого необходимо в кроне вызвать всего одну команду - cli_dispatcher
.
php index.php cli_dispatcher
В каждый установленный промежуток времени cli_dispatcher, пробегая по проекту, будет собирать все cli-команды и проверять, была ли каждая запущена в установленный промежуток времени. И если нет, то будет запускать.
В том классе, где описаны cli-команды, необходимо добавить специальные методы everyN(), dailyH_m()
.
- everyN() - где N - минуты. Запускать каждые N минут.
- dailyH_m() - где H_m - часы_минуты. Запускать ежедневно в H часов m минут. Запуск будет произведен 1 раз в сутки.
// app/components/Forum/CLI.php class Component_Forum_CLI extends CMS_CLI_Handler implements Core_ModuleInterface { public function send_email() { // формирование и отправление письма } public function daily4_15() { $this->send_email(); } }
- daily_service() - запуск будет производиться один раз в сутки в момент времени, указанный в настройках. Формат времени - ЧЧ<разделитель>мм. Разделитель может быть любым символом.
// components/NameComponent/config/component.php return array( 'cli' => array( 'daily_service' => '15-30', ), ... );