Как создать консольную команду в Laravel?php-82

1. Генерация команды

Используйте Artisan для создания новой команды:

php artisan make:command SendEmailsCommand

Это создаст файл в app/Console/Commands/SendEmailsCommand.php с базовой структурой.

2. Структура класса команды

Сгенерированный класс содержит:

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SendEmailsCommand extends Command
{
    protected $signature = 'app:send-emails';
    protected $description = 'Send emails to all users';

    public function handle()
    {
        // Логика команды
    }
}

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

После создания команду нужно зарегистрировать в app/Console/Kernel.php:

protected $commands = [
    Commands\SendEmailsCommand::class,
];

4. Определение сигнатуры команды

Базовые параметры:

protected $signature = 'email:send {user}';

Опциональные параметры:

protected $signature = 'email:send {user?}';

Флаги:

protected $signature = 'email:send {--queue}';

Массивы параметров:

protected $signature = 'email:send {user*}'.

5. Пример сложной команды

protected $signature = 'email:send
                        {user : The ID of the user}
                        {--queue : Whether to queue the emails}
                        {--chunk=100 : Number of emails per chunk}';

6. Обработка ввода

В методе handle() доступны методы для работы с вводом:

public function handle()
{
    $userId = $this->argument('user');
    $shouldQueue = $this->option('queue');
    $chunkSize = $this->option('chunk');

    $this->info("Sending emails to user $userId");
}

7. Вывод информации

Основные методы вывода:

$this->info('Success message');    // Зеленый текст
$this->error('Error message');    // Красный текст
$this->line('Simple message');    // Обычный текст
$this->comment('Comment text');   // Желтый текст

Таблицы:

$headers = ['Name', 'Email'];
$users = User::all(['name', 'email'])->toArray();

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

Прогресс-бар:

$users = User::all();

$this->output->progressStart($users->count());

foreach ($users as $user) {
    // Отправка email
    $this->output->progressAdvance();
}

$this->output->progressFinish();

8. Интерактивные команды

Запрос ввода:

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

Подтверждение:

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

Выбор из списка:

$role = $this->choice(
    'What role should the user have?',
    ['user', 'editor', 'admin'],
    'user'
);

9. Пример реальной команды

namespace App\Console\Commands;

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

class SendEmailsCommand extends Command
{
    protected $signature = 'email:send
                            {--users=* : User IDs to send emails}
                            {--queue : Queue the emails}
                            {--chunk=100 : Number of emails per chunk}';

    protected $description = 'Send newsletter emails to users';

    public function handle()
    {
        $query = User::where('subscribed', true);

        if ($ids = $this->option('users')) {
            $query->whereIn('id', $ids);
        }

        $users = $query->cursor();
        $total = $query->count();
        $chunkSize = (int)$this->option('chunk');

        $this->info("Starting to send $total emails...");

        $users->chunk($chunkSize, function ($usersChunk) {
            foreach ($usersChunk as $user) {
                if ($this->option('queue')) {
                    Mail::to($user)->queue(new NewsletterMail());
                } else {
                    Mail::to($user)->send(new NewsletterMail());
                }
            }

            $this->info("Sent batch of " . count($usersChunk) . " emails");
        });

        $this->info('All emails sent successfully!');
    }
}

10. Тестирование команд

Пример теста с PHPUnit:

public function test_send_emails_command()
{
    $this->artisan('email:send', ['--users' => [1, 2]])
         ->expectsOutput('Starting to send 2 emails...')
         ->assertExitCode(0);
}

Резюмируем:

  1. Консольные команды в Laravel:

    • Создаются через make:command
    • Регистрируются в Console/Kernel.php
    • Выполняются через Artisan CLI
  2. Ключевые возможности:

    • Гибкая система аргументов и опций
    • Разнообразные методы ввода/вывода
    • Поддержка прогресс-баров и таблиц
    • Интеграция с сервисами Laravel
  3. Best Practices:

    • Используйте четкие описания команд
    • Разделяйте логику на сервисные классы
    • Добавляйте валидацию входных данных
    • Реализуйте обработку ошибок
  4. Производительность:

    • Для больших данных используйте cursor()
    • Применяйте chunk для обработки по частям
    • Для длительных операций используйте очереди

Для production-окружения:

  • Добавляйте команды в планировщик (Scheduler)
  • Логируйте выполнение команд
  • Настройте мониторинг длительных операций
  • Документируйте доступные команды для команды