Как вы наверное знаете, в php есть интересная функция для обработки данных, поступающих из командной строки: getopt. Но есть одна маленькая проблема — она неправильно работает в CodeIgniter, да и не совсем удобная.
А так как у меня было немного свободного времени, желание написать что-нибудь своё опен сорсное, попробовать в деле github (сижу на hg+bitbucket), и наконец сделать что-то полезное для тухнущего CodeIgniter и его сообщества, я решил написать свой костыль, призванный немного скрасить написание cli скриптов на данном фреймворке.
Оно умеет самый минимум — искать заданные аргументы, производить их валидацию (если не указаны обязательные) и выводить подсказки по использованию вашего скрипта, а при желании легко может быть допилено для использования без привязки к CodeIgniter:
Использование
Собственно говоря, при создании библиотеки я постарался сделать её использование привычным для людей, работающих с CodeIgniter, поэтому её использование в чем то похоже на использование стандартной библиотеки Form_Validation.
Лучше всего это рассмотреть на примере:
1. Для начала качаем библиотеку с гитхаба и кладём её в папку */application/libraries/.
2. Затем создаем контроллер, который будет использоваться в командной строке:
<?php if ( ! defined("BASEPATH")) exit("No direct script access allowed");
class Cli extends MY_Controller {
public function __construct() {
parent::__construct();
if(!$this->input->is_cli_request()) {
show_404();
}
}
}
Обратите внимание на строку, где проверяется, запускается ли этот контроллер из командной строки. Мы же не хотим чтобы какой-нибудь злодей получил доступ к нашему скрипту через веб-сайт!
3. Теперь создадим метод, использующий нашу библиотеку:
public function hello() {
// Add an argument for cli interaction
$argumets = array(
array('alias' => '-n',
'arg' => '--name',
'help' => 'the name, we say hello to',
'type' => 1)
);
// Initialize library with arguments array
$this->load->library("command_line", $argumets);
// Validate input
if (!$this->command_line->valid_input()) {
// If not valid, print some help
print $this->command_line->get_help();
} else {
// Else do your code
print("Hello " . $this->command_line->get_argument('-n') . "!" . PHP_EOL);
}
}
Разберем этот код подробнее.
Сначала мы создали массив с возможными параметрами для нашего скрипта:
- arg — основное название аргумента (напр. --name).
Обязательно для заполнения, если не указан alias - alias — сокращенное название элемента (напр. -n).
Обязательно для заполнения, если не указан arg - help — строка, которая будет выводиться при запросе помощи (у нас оно говорит о том, что это имя человека)
- type — один из трёх возможных видов аргумента: 0 — для опциональных, 1 — для обязательных и 2 — для триггеров (boolean).
Стоит отметить, что оциональные и триггеры сами определяют своё значение. Например, неуказанные примет значение FALSE, а указанный триггер без параметров станет TRUE. Если же не указать обязательный, при этом подав какие-либо из существующих параметров на вход, то вылезет ошибка и скрипт не исполнится.
Итак, задав конфиг, мы инициализируем нашу библиотеку и проверяем входящие параметры на валидность, прямо как в Form_validation!
if (!$this->command_line->valid_input())
Если она не валидна — нет параметров, или произошла какая-либо ошибка, мы просто вызываем метод, который подскажет нам что не так:
print $this->command_line->get_help();
Если же всё прошло как надо, то мы можем выполнить свой код, получив параметры аргументов с помощью метода get_argument(). Вы сможете обратиться к ним как по полному названию, так и по алиасу:
$this->command_line->get_argument('-n') === $this->command_line->get_argument('--name')
4. Теперь, когда всё готово, открываем командую строку и проверяем наш скрипт:
php index.php cli home
Так как вы не ввели никаких аргументов, он дружелюбно подскажет вам, как им пользоваться:
Usage: php index.php cli hello [OPTIONS]
Options are:
-n, --name the person's name, we say hello to
Так, надо ввести имя:
php index.php cli home -n Habrahabr
Что выведет следующее:
Hello Habrahabr!
Заключение
Как видите, библиотека совсем примитивная, и реализует лишь самую базу функций, могущих потребоваться при работе с командной строкой. Тем не менее, она может сэкономить немного времени на разработке системных cli скриптов, используемых, скажем, для задач в cron. Это действительно удобно — можно использовать весь написанный код ваших моделей и библиотек для создания системных задач, таких, как, например, генерация карты сайта или пересчет каких-либо показателей.
Также хочу заранее предупредить, что пока версия библиотеки довольно таки сырая, и возможно возникновение каких-либо багов. С удовольствием выслушаю ваши комментарии по этому поводу, а так же буду рад, если вы вложите свою лепту, присоединившись к разработке на github.
Автор: TrueDrago