Пользовательская консольная команда Laravel, вызывающая конструктор всех других пользовательских команд

У меня есть набор консольных команд, зарегистрированных в app / Console / Kernel.php. Мой Kernel.php выглядит так:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Commands\ConsoleCommand1::class,
        Commands\ConsoleCommand2::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
     *
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // Some code
    }
}

Структура класса консольных команд выглядит так:

<?php namespace App\Console\Commands;

use Illuminate\Console\Command;
use Dependancy;

class ConsoleCommand1 extends Command
{
    protected $signature = ‘console_command_1’;
    protected $description = ‘This is the description’;
    private $dependancy;

    public function __construct(Dependancy $dependancy)
    {
        parent::__construct();
        $this->dependancy = $dependancy;
    }

    public function handle()
    {
        // Some code
    }
}

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

Например, если я выполняю команду «php artisan console_command_1», выполняются конструкторы как «php artisan console_command_1», так и «php artisan console_command_2», и наоборот. На самом деле я хочу, чтобы вызывался только конструктор «фактически выполненной ремесленной команды».

Так устроена консольная команда Laravel или я что-то делаю не так? Любая помощь высоко ценится.


person Tibin Paul    schedule 28.03.2016    source источник


Ответы (1)


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

1. Когда вы запускаете консольную команду, точкой входа является файл artisan, расположенный в корне вашего проекта. Это создает экземпляр ядра и вызывает на нем метод handle, передавая полученные аргументы ( а именно: имя команды artisan и любые дополнительные аргументы, переданные для нее).

2. Метод handle ядра будет запустите команду artisan, и для этого потребуется экземпляр консольного приложения (внутренне идентифицируемый как Artisan), которому необходимо будет вызвать _ 5_, чтобы создать список команд, чтобы он мог проверить, допустимо ли текущее имя команды. Этот метод создаст make новый экземпляр для каждого команда, зарегистрированная в ядре (те, которые вы определили, а также все стандартные, загруженные из _ 7_).


На самом деле, поскольку в Kernel вы регистрируете команду через ссылку на имя класса:

Commands\ConsoleCommand1::class

И имя команды является защищенным свойством этого класса:

protected $signature = ‘console_command_1’;

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

person Bogdan    schedule 28.03.2016
comment
Действительно интересный материал. Спасибо за четкий ответ @Bogdan. - person Tibin Paul; 29.03.2016
comment
Забавно, что в документации показан пример с конструктором, но нет предупреждений о его использовании. Похоже, подписи нужно переместить в ядро ​​в массиве assoc. - person jminkler; 09.06.2016
comment
Итак, если есть 10 классов консольных команд, laravel продолжит создавать классы? Потому что в моем случае каждые 10 секунд я получаю логи от конструкторов команд. Забавно, что я заметил это сейчас. - person Farveaz; 17.10.2016
comment
Даже не упоминается в последней документации ... это должно быть частью этого - person chickenchilli; 14.01.2020