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',
	),
	...
);
Метки: CLI, CMS
23.03.2015
Все статьи