В предыдущей статье мы разобрали новый синтаксис создания Artisan команд.
Сегодня же мы поговорим о возможностях Artisan команд для ввода и вывода данных. Большая часть данной публикации будет посвящена разбору новых возможностей Laravel 5.1, чтобы разобраться с возможностями расширенного вывода.
На заметку: Artisan команды построены на Symfony Console компоненте, так что если вы действительно хотите углубиться в тему, узнать больше можно там.
В кратце напомню на что похожа запись определения объекта команды в 5.1:
protected $signature = 'command:name {argument} {optionalArgument?} {argumentWithDefault=default} {--booleanOption} {--optionWithValue=} {--optionWithValueAndDefault=default} ';
Здесь мы можем видеть методы, которые возможно использовать в пределах handle() метода Вашей команды для получения и отображения данных.
Стандартный ввод
$this->argument('argumentName')
Метод аргумента позволяет Вам получить значение аргумента, который был определен в списке параметров.
Потому, если Ваша запись определения выглядит как do:thing {awesome} и пользователь запустит:
php artisan do:thing fantastic, $this->argument('awesome')
То возвращено будет fantastic.
Обратите внимание также на то, что если Вы используете аргумент, который не обязателен, при этом не задано значение по умолчанию и пользователь ничего не заполняет, то в результате выполнения будет возвращено значение null.
$this->option('optionName')
Также как и метод аргумента, метод параметра вернет значение параметра.
Если параметр определен как булев (--queued, --doItAwesomely), этот метод вернет true в случае успешного выполнения и false в противном случае.
Потому, если Ваша запись определения выглядит как go {--boldly} и пользователь запускает:
php artisan go --boldy, $this->option('boldly')
Возвращено будет значение true.
$this->argument() и $this->option()
Если Вы не передаете параметры в методы агрумента и параметра, они оба вернут массив всех заданных в них параметров и их значений.
Итак, если задан маршрут jump:on {thing1} {thing2} и пользователь запускает:
php artisan jump:on rock boulder, $this->argument()
В обоих случаях возвращен будет массив:
[ 'command': 'jump:on', 'thing1': 'rock', 'thing2': 'boulder' ]
Стандартный вывод
Когда Вы пишете Ваш handle() метод, обычно вы желаете послать вывод конечному пользователю. Существует несколько вариантов для этого.
Все четыре простых стандартных метода ($this->info(), $this->comment(), $this->question(), и $this->error()) позволяют Вам передать любую строку пользователю в виде уведомления:
$this->info('Finished syncing data');
Проверьте все цвета:
Расширенный ввод
Ну а что, если Вы желаете написать скрипт, который позволит Вам иметь различные этапы поиска информации пользователем? Или же условный поиск информации в зависимости от предыдущих запросов, или в зависимости от части операций в команде?
$this->ask()
Отправляем вопрос пользователю и получаем ответ:
public function handle() { $name = $this->ask('What is your name?'); $this->info("Hello, $name"); }
$this->secret()
Работает так же как и ask(), но скрывает печатаемые символы:
public function handle() { $password = $this->secret('What is your password?'); $this->info("This is really secure. Your password is $password"); }
$this->confirm()
Ну а что если необходимо получить лишь ответ да или нет?
public function handle() { if ($this->confirm('Do you want a present?')) { $this->info("I'll never give you up."); } }
$this->anticipate() и $this->choice()
Ну а как насчет нестандартных вариантов? Anticipate метод позволяет Вам внедрить автодополнение (но оставляет возможность пользователю заполнить любой ответ), а choice метод заставит пользователя выбрать из предложенных вариантов.
public function handle() { $name = $this->anticipate( 'What is your name?', ['Jim', 'Conchita'] ); $this->info("Your name is $name"); $source = $this->choice( 'Which source would you like to use?', ['master', 'develop'] ); $this->info("Source chosen is $source"); }
В итоге получим:
Расширенный вывод
Laravel 5.1 предоставляет два новых способа вывода форм: таблица и индикатор выполнения.
$this->table()
Для использования метода таблиц требуется заполнить два параметра: шапку и данные таблицы.
Итак, начнем с самописной таблицы:
public function handle() { $headers = ['Name', 'Awesomeness Level']; $data = [ [ 'name' => 'Jim', 'awesomeness_level' => 'Meh', ], [ 'name' => 'Conchita', 'awesomeness_level' => 'Fabulous', ], ]; /*такая конструкция будет также отлично работать $data = [ ['Jim', 'Meh'], ['Conchita', 'Fabulous'] ]; */ $this->table($headers, $data); }
Получим следующий вывод:
И как Вы можете видеть в документации, это отличный инструмент для простого экспорта данных с Eloquent:
public function handle() { $headers = ['Name', 'Email']; $users = App\User::all(['name', 'email'])->toArray(); $this->table($headers, $users); }
Пример создан при помощи Symfony Table Helper.
Индикатор выполнения
Это похоже на магию, но вывод индикатора процесса выполнения теперь стал весьма простой задачей, если воспользоваться Symfony Progress Bar Component:
public function handle() { $this->output->progressStart(10); for ($i = 0; $i < 10; $i++) { sleep(1); $this->output->progressAdvance(); } $this->output->progressFinish(); }
В итоге получим такую красоту:
Давайте разберем наш пример по частям. Во-первых мы укажем в прогресс-баре сколько "units" мы будем использовать:
$this->output->progressStart($numUnits);
Далее, при каждой обработке такого юнита, мы добавим к прогресс бару единицу:
$this->output->progressAdvance();
В конце, мы отметим задачу как завершенную:
$this->output->progressFinish();
Обратите внимание на то, что данный синтаксис обернут вокруг компонента Symfony Progress Bar. Там можно узнать больше информации по возможностям данной функции.
Подводя итоги
Ну вот и все, теперь вы профессиональный координатор ввода/вывода данных Artisan командами. Можете добавить это себе в резюме.
Перевод статьи Matt Stauffer "Advanced input & output with Artisan commands, tables, & progress bars in Laravel 5.1".