Блог Vaden Pro

Все о самостоятельном создании и продвижении сайтов

Расширенный ввод и и вывод данных Artisan командами в Laravel 5.1

Раздел: 

В предыдущей статье мы разобрали новый синтаксис создания Artisan команд.

Сегодня же мы поговорим о возможностях Artisan команд для ввода и вывода данных. Большая часть данной публикации будет посвящена разбору новых возможностей Laravel 5.1, чтобы разобраться с возможностями расширенного вывода.

Laravel Artisan input output

На заметку: 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');

Проверьте все цвета:

Artisan цвета вывода

Расширенный ввод

Ну а что, если Вы желаете написать скрипт, который позволит Вам иметь различные этапы поиска информации пользователем? Или же условный поиск информации в зависимости от предыдущих запросов, или в зависимости от части операций в команде?

$this->ask()

Отправляем вопрос пользователю и получаем ответ:

public function handle()
{
    $name = $this->ask('What is your name?');
 
    $this->info("Hello, $name");
}

Artisan ask

$this->secret()

Работает так же как и ask(), но скрывает печатаемые символы:

public function handle()
{
    $password = $this->secret('What is your password?');
 
    $this->info("This is really secure. Your password is $password");
}

Artisan secret

$this->confirm()

Ну а что если необходимо получить лишь ответ да или нет?

public function handle()
{
    if ($this->confirm('Do you want a present?')) {
        $this->info("I'll never give you up.");
    }
}

Artisan confirm

$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");
}

В итоге получим:

Artisan choise anticipate

Расширенный вывод

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);
}

Получим следующий вывод:

Artisan table

И как Вы можете видеть в документации, это отличный инструмент для простого экспорта данных с 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();
}

В итоге получим такую красоту:

Artisan progress bar

Давайте разберем наш пример по частям. Во-первых мы укажем в прогресс-баре сколько "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".

Больше о нововведениях версии Laravel 5.1.