Artisan Консоль

Содержание:

Введение

Artisan это интерфейс командной строки вкючённй в Ларавел. Он предоставляет много полезный команд, которые могут помочь вам во время написание вашего проекта. Чтобы просмотреть список доступных команд Artisan, вы можете использовать команду list:

php artisan list

Каждая команда также включает экран помощи, которые показывает и описывает доступные аргументы и опции команды. Чтобы увидеть экран помощи, введите имя команды с help:

php artisan help migrate

Tinker (REPL)

Все приложения Ларавел вкючаеют Tinker, который позволяет вам взаимодействовать с приложением Ларавел через командную линию, включая Eloquent ORM, задания, события и другое. Чтобы войти в окружение Tinker, запустите команду Артизан tinker:

php artisan tinker

Вы можете опубликовать файл конфигурации Tinker испольуя команду vendor:publish:

php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"

Белый лист команд

Tinker использует белый лист для определения какае команды Artisan разрешены внутри оболочки. По умолчанию, вы можете выполнить команды clear-compiled, down, env, inspire, migrate, optimize, и up. Если вы хотите добавить в белый список больше команд вы можете добавить их в массив commands в ваш файл конфигурации tinker.php:

'commands' => [
    // App\Console\Commands\ExampleCommand::class,
],

Черный лист псевдонимов

Обычно, Tinker автоматически создает псевдонимы классов по мере необходимости в Tinker. Но вы можете захотеть сделать так, чтобы не давать псевдонимы определённым классам. Вы можете сделать это путём перечисления классов в массиве dont_alias в вашем файле конфигурации tinker.php:

'dont_alias' => [
    App\User::class,
],

Написание команд

В дополнение к командам входящих в Artisan, вы можете добавить ваши собственные команды. По умолчанию команды хранятся в папке app/Console/Commands. Конечно, вы легко можете выбрать другую директорию, до тех пор пока они могут быть загружены Composer.

Генерирование команд

Чтобы создать новую команду, используйте команду Artisan make:command. Эта команда создаст новый класс команды в папке app/Console/Commands. Не нужно беспокоиться если эта папка пока не существует для вашего приложения, после первого выполнения команды make:command она будет создана автоматически. Сгенерированная команда будет включать типовой набор свойств и методов, которые присутствуют во всех командах:

php artisan make:command SendEmails

Структура команды

После генерации команды, вам нужно заполнить свойства класса signature и description, который будет использоваться при отображении команды для list экрана. Метод handle будет вызван после выполнения команды. Вы можете разместить логику вашей команды в этом методе.

Для более широкого повторного использования кода рекомендуется держать команды консоли легкими и откладывать их выполнение до момента, когда сервисы приложения завершат свои задачи. В приведённом ниже примере обратите внимание, что мы ввели класс, чтобы сделать "тяжелую работу" по отправке электронных писем.

Давайте взглянем на пример команды. Заметьте, что мы можем внедрить любые необходимые зависимости в метод команды handle. Сервис контейнер Ларавел автоматически внедрит все зависимости, которые вписаны в метод:

<?php

namespace App\Console\Commands;

use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;

class SendEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:send {user}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send drip e-mails to a user';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @param  \App\DripEmailer  $drip
     * @return mixed
     */
    public function handle(DripEmailer $drip)
    {
        $drip->send(User::find($this->argument('user')));
    }
}

Команды замыканий

Команды основанные на замыкании предоставляют альтернативу для определения команд консоли как классов. Можно воспринимать команды замыкания как ильтернативу для классов команд таким же опражом как и замыкание маршрута альтернатива для контроллеров. Внутри метода commands вашего app/Console/Kernel.php файла, Laravel загружает routes/console.php файл:

/**
 * Register the Closure based commands for the application.
 *
 * @return void
 */
protected function commands()
{
    require base_path('routes/console.php');
}

Даже если этот файл не определяет маршруты HTTP, он определяет консольные точки входа (маршруты) для вашего приложения. Внутри файла, вы можете определить все маршруты основанные на замыкании, используя метод Artisan::command. Метод command принимает два аргумента: подпись команды и замыкание, которе получает аргументы и опции команд.

Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
});

Замыкание привязано к нижестоящему экземпляру команды, поэтому вы имеете полный доступ ко всем вспомогательным методам к которым вы обычно можете получить доступ к полному классу команд.

Вписывание зависимостей

Дополнительно к получению аргуметов и опций команды, можно вписать дополнительные зависимости, которые вы бы хотели реализовать через сервис контейнер:

use App\User;
use App\DripEmailer;

Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
    $drip->send(User::find($user));
});

Описание команд замыкания

При определении команд основанных на замыкании, вы можете использовать метод describe, чтобы добавить описание к команде. Это описаине будет отображаться при выполнении команд php artisan list или php artisan help:

Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
})->describe('Build the project');

Определение вводных ожиданий

При написании команд консоли, обыкновенно происходит сбор входных данных через аргументы или параметры. Laravel позваляет очень удобно определять входные данные, которые вы ожидаете от пользователя используя свойство signature для ваших команд, которое позволяет вам определить имя, аргументы и параметры в едином, выразительном, похожем на маршрут синтаксисе.

Аргументы

Все аргументы и опции, предоставленные пользователем заключены в фигурные скобки. В следующем примере, команда определяет один обязательный required аргумент: user:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user}';

Вы также можете сделать аргументы необязательными и определить базовае значенине для аргументов:

// Optional argument...
email:send {user?}

// Optional argument with default value...
email:send {user=foo}

Опции

Опции, как и аргументы, другая форма вводных данных пользователя. Для опций используется двойной дефис (--) в командной строке. Существует два типа опций: которые получают значение и которые нет. Опции, которые не пулчают значения выступают в качестве своего рода логического свитчера. Давайте взглянем на пример такого типа опций:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user} {--queue}';

В этом примере, перключатель --queue может быть указан во время вызова команды Artisan. Если был передан указатель --queue, тогда значение опции будет true. В противном случае значение будет false:

php artisan email:send 1 --queue

Опции со значениями

Давайте взглянем на опции, которые ожидают значение. Если пользователь должен указать значение для опции, добавьте суффикс со знаком =:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user} {--queue=}';

В этом примере, пользователь должен передавать значение для опции таким образом:

php artisan email:send 1 --queue=default

Вы можете приписать базовое значение для опции после имени опции. Если не передано значение опции пользователем, будет использовано базовое значение:

email:send {user} {--queue=default}

Ярлыки опций

Чтобы назначить ярлык при определении опции, вы можете указать его перед именем опции и использовать разделитель | чтобы отделить ярлык от полного имени параметра:

email:send {user} {--Q|queue}

Входящие массивы

Если вы хотите определить аргументы или опции, которые ожидают входящий массив, вы можете использовать * символ. Теперь, давайте взглянем на пример, который указывает аргумент в виде массива:

email:send {user*}

При вызове этого метода, аргументы user могут быть переданы в порядке, указанном из консоли. Например, следующая команда установит значение user в ['foo', 'bar']:

php artisan email:send foo bar

При определении опции, которая ожидает входящий массив, каждая значение опции передаваемов в команду должно иметь префикс с именем опции:

email:send {user} {--id=*}

php artisan email:send --id=1 --id=2

Входящие описания

Вы можете приписать описания ко входящим аргумента и опциям путём отделения параметра от описания используя двоеточие. Если нужно больше места для определения команды, можете легко распространить определение на несколько линий:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send
                        {user : The ID of the user}
                        {--queue= : Whether the job should be queued}';

Команды ввода, вывода

Получение входных данных

Пока выполняется команда, вам очевидно потребуется получить доступ к значения для аргументов и опций принятых командой. Чтобы это сделать, вам необходимо использовать методы argument и option:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $userId = $this->argument('user');

    //
}

Если вам нужно получить все аргументы как массив array, вызовите метод arguments:

$arguments = $this->arguments();

Опции могут быть получены также легко, как и методы. Чтобы получить все опции как массив, вызовите метод options:

// Retrieve a specific option...
$queueName = $this->option('queue');

// Retrieve all options...
$options = $this->options();

Если аргумент или опция не существует, вернётся null.

Вывод данных ввода

В дополнение к отображению вывода, вы можете также обратиться к пользователю во время выполнения команды. Метод ask будет задавить вопрос пользователю, принимать ввод и возвращать пользователя обратно к командной строке:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $name = $this->ask('What is your name?');
}

Метод secret похож на метод ask, но входные данные пользователя не будут видны им. Этот метод может быть полезным для чувствительной информации, такой как пароль:

$password = $this->secret('What is the password?');

Запрос на потверждение

Если вам необходимо запросить у пользователя сделать простое потверждение, вы можете использовать метод confirm. По умолчанию, этот метод вернёт false. Однако, если пользователь вводит y или yes в строке, тогда метод вернёт true.

if ($this->confirm('Do you wish to continue?')) {
    //
}

Автозаполнение

Метод anticipate может быть использон для обеспечения автозаполнения для возможных вариантов. Пользователь также может выбирать любой ответ, не смотря на подсказки автозаполнения:

$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

Вопросы с множественным выбором

Если вам необходимо дать пользователю предопределённый набор пунктов выбора, вы можете использовать метод choice. Вы можете установить массив значений по умолчанию, если не выбран ни один из вариантов:

$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $defaultIndex);

Написание выхода

Для отправки вывода используйте методы line, info, comment, question и error. Каждый из этих методов будет использовать соответсвующие ANSI цвета для их целей. Например, давайте отобразим общую информацию пользователю. Обычно, метод info будет показан в консоли как зелёный цвет:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $this->info('Display this on the screen');
}

Чтобы отобразить сообщение ошибки, используйте метод error. Текст сообщения ошибки обычно показан в красном:

$this->error('Something went wrong!');

Если бы вы хотели отобразить вывод вез цветового оформления, используйте метод line:

$this->line('Display this on the screen');

Оформление таблиц

Метод table делает легким форматирование нескольких рядов и колонок данных. Просто передайте заголовки и ряды в метод. Ширина и высота будет динамически посчитана основываясь на представленных данных:

$headers = ['Name', 'Email'];

$users = App\User::all(['name', 'email'])->toArray();

$this->table($headers, $users);

Полоса выполнения

Для длинных заданий может быть полезно показать индикаторы прогресса. Использование объекта вывода, мы можем начать, продвинуть или остановить полосу прогресса. Во-первых, определите число шагов, которые необходимо выполнить для завершения. После чего, продвигайте индикатор выполнения после каждого шага:

$users = App\User::all();

$bar = $this->output->createProgressBar(count($users));

$bar->start();

foreach ($users as $user) {
    $this->performTask($user);

    $bar->advance();
}

$bar->finish();

Для использования расширенных опций, ознакомьтесь с документацией Symfony полоса прогресса.


Регистрация команд

Из-за вызова метода load в ядре консоли метода commands, все команды внутри папки app/Console/Commands автоматически будут зарегистрированы в Артизан. По факту, вы можете сделать дополнительную загрузку в методе load для сканирования других папок:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');
    $this->load(__DIR__.'/MoreCommands');

    // ...
}

Вы также можете зарегистрировать команды вручную путём добавления имени класса в свойство $commands вашего файла app/Console/Kernel.php. При загрузке Artisan, все команды перечисленные в этом свойстве будут задействованы через сервис контейнер и зарегистрированы в Artisan:

protected $commands = [
    Commands\SendEmails::class
];

Программное выполнение команд

Иногда вы можете захотеть выполнить команду Artisan за пределами командной строки. Например, вы захотеть запустить команду Артизан из маршрута или контроллера. Вы можете использовать метод call для фасада Artisan для реализации задуманного. Метод call может принимать и имя команды и класс в качестве первого аргумента и массив параметров команды в качестве второго аргумента. Код выхода будет возвращен:

Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
});

Как альтернатива, вы можете передать команду Artisan полностью, строкой в методе call:

Artisan::call('email:send 1 --queue=default');

Используя метод queue для фасада Artisan, вы можете даже ставить выполнение команд Artisan в очередь, и они будут выполнять в фоновом режиме обработчиками очередей. Перед использованием этого метода, убедитесь в том, что настроили очереди и запустили слушателя:

Route::get('/foo', function () {
    Artisan::queue('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
});

Вы можете также указать очередь или соединение куда должна отправляться команда Artisan:

Artisan::queue('email:send', [
    'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');

Передача значений массива

Если ваша команда определяет опцию, которая принимает массив, тогда вы можете передать массив значений в эту опцию:

Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
        'user' => 1, '--id' => [5, 13]
    ]);
});

Передача логических значений

Если вам нужно указать опцию, которая не принимет строкавых значений, таких как --force для команды migrate:refresh, вам необходимо передать true или false:

$exitCode = Artisan::call('migrate:refresh', [
    '--force' => true,
]);

Вызов команд из других команд

Иногда вы можете захотеть вызвать другие команды во время выполнения команды Artisan. Вы можете так сделать используя метод call, который принимает имя команды и массив параметров команды:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $this->call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
}

Если вы хотите вызвать другую команду консоли и скрыть все входные данные, вы можете использовать метод callSilent. Метод callSilent имеет такую же подпись, как и метод call:

$this->callSilent('email:send', [
    'user' => 1, '--queue' => 'default'
]);