В большинство проектах, некоторые задачи нужно выполнять при помощи планировщика заданий crontab. Например, это может быть рассылка уведомлений или новостей сайта, сбор и обработка статистики, формирование и отправка отчетов администраторам и т.п. В этих случаях скрипты необходимо запускать из командной строки.
В списке официальных модулей Kohana 3.3, есть такой замечательный модуль Minion. Он как раз специально предназначен для таких задач как CLI (обычно это задачи для Cron'а).
Подготовка
Для начала нужно разрешить загрузку модуля Minion в файле bootstrap.php (Он там по умолчанию есть, но закомментирован).
Kohana::modules(array( // 'auth' => MODPATH.'auth', // Basic authentication // 'cache' => MODPATH.'cache', // Caching with multiple backends // 'codebench' => MODPATH.'codebench', // Benchmarking tool // 'database' => MODPATH.'database', // Database access // 'image' => MODPATH.'image', // Image manipulation 'minion' => MODPATH.'minion', // CLI Tasks // 'orm' => MODPATH.'orm', // Object Relationship Mapping // 'unittest' => MODPATH.'unittest', // Unit testing // 'userguide' => MODPATH.'userguide', // User guide and API documentation ));
Копируем файл minion из modules/minion/ в нужное место (оттуда будет запускаться планировщиком задач). Затем вносим в него правки, указываем местоположение файла index.php.
Для того чтобы проверить правильно все ли настроено, запустите из консоли команду:
php minion --help
Данная команда выведет краткую информацию о модуле Minion.
Использование модуля Minion
Для примера создадим самую простую задачу, которая будет при запуске говорить нам "Hello world!". Для этого создадим файл application/classes/Task/Test.php с даным кодом:
<?php defined('SYSPATH') or die('No direct script access.'); /** * Test class * * @author novisasha */ class Task_Test extends Minion_Task { protected function _execute(array $params) { Minion_CLI::write('Hello World!'); } }
Если запустить команду
php minion --task=Test
то выведется наша фраза "Hello World!".
Каждая задача наследуется от класса потомка Minion_Task, а за выполнение задачи отвечает метод _execute.
Также в метод _execute можно передать аргумент $params, который будет содержать в себе параметры, переданные в задачу через командную строку. Переменная $params, содержит в себе все параметры, кроме специально зарезервированных, таких как --task и --help.
Например:
php minion --task=Test --foo=bar
Данная команда передаст парамерт foo со значением bar.
Кстати, прежде чем передавать параметры в консоле, их нужно заранее объявить в задаче и выставить значения по умолчанию, иначе вы получите сообщение об ошибку в Kohana.
Например:
<?php defined('SYSPATH') or die('No direct script access.'); /** * Test class * * @author novisasha */ class Task_Test extends Minion_Task { protected $_options = array( // param name => default value 'name' => 'World', ); protected function _execute(array $params) { Minion_CLI::write('Hello '. $params['name'] .'!'); } }
Теперь при вызове:
php minion --task=Test
Мы увидим фразу "Hello World!", т.к. использовано значение по умолчанию, а если же мы явно зададим параметр name:
php minion --task=Test --name=Ivan
то нам выведется фраза "Hello Ivan!"
Ввод и вывод данных
Класс Minion_CLI содержит несколько методов для работы с выводом и вводом данных.
Для чтения данных из потока существует метод read:
Minion_CLI::read($text = '', array $options = NULL)
Рассмотрим несколько примеров:
Minion_CLI::read();
Просто прочитает одну строку
$name = Minion_CLI::read('Enter name');
Выведет строку 'Enter name'и присвоит переменной $name введеный вами ответ:
$gender = Minion_CLI::read('Gender', array('m', 'f'));
Выведет строку 'Gender [ m, f ]' и присвоит переменной $gender введеный вами ответ. Если же ответ будет не 'm' или 'f', то Minion будет выдавать сообщение об ошибку 'Gender is not a valid option. Please try again.' до получения корректного результата. Кстати буквы в фильтре регистрозависимы, т.е. значение 'M' считается некорректным!
Для записи данных в поток существует метод write:
Minion_CLI::write($text = '')
Рассмотрим несколько примеров:
Minion_CLI::write();
Просто перейдет на следующую строку
Minion_CLI::write('Hello world!');
Выведет фразу в консоль
Minion_CLI::write(array('Hello world!', 'Hello people!'));
Выведет несколько строк
Кроме чтения и записи есть еще нескольок полезных методов, это write_replace:
Minion_CLI::write_replace($text = '', $end_line = FALSE)
Метод write_replace заменяет предыдущую стороку новым сообщением. Это может быть полезно, например, для имитации загрузки. Также флаг $end_line нужно исползовать для фиксации строки (добавляется конец строки).
Метод wait используется для паузы между действиями.
Minion_CLI::wait($seconds = 0, $countdown = false)
Время задержки указывается в секундах. Флаг $countdown указывает будет ли в консоль выводится отсчет времени или нет.
Пример:
Minion_CLI::write_replace('H'); Minion_CLI::wait(1); Minion_CLI::write_replace('He'); Minion_CLI::wait(1); Minion_CLI::write_replace('Hel'); Minion_CLI::wait(1); Minion_CLI::write_replace('Hell'); Minion_CLI::wait(1); Minion_CLI::write_replace('Hello', TRUE);
Данный код выведет слово 'Hello' с эффектом печатающей машинки.
Справка в задачах
Модуль имеет зарезервированый ключ --help, по которому он отображает справку п омодулю в целом или если указана в параметре --task - по конкретной задачи. Например если в нашей задачи вызвать справку:
php minion --task=Test --help
то получим вот такую информацию:
Usage ======= php minion.php --task=test [--option1=value1] [--option2=value2] Details ======= Author: novisasha Description =========== Test class
Даная информация берется из PHPDOC к класу Task_Test. Таким образом разработчики Kohana облегчают работу, позволяя разом убивать двух зайцев - документировать исходники и писать документацию для задач.
Альтернативный запуск Задач
Запускать задачи можно и без использования скрипта minion. Любые CLI-команды будут перенаправлены к модулю Minion, поэтому вместо
php minion --task=Test
можно использовать
php index.php --task=Test
Unable to find a route to match the URI: --task=Test
Vladimir, какую команду Вы запускали в консоле и какой код у Вас в файле с задачей application\classes\Task\Test.php ?