2016-03-28 14 views
2

Ich habe eine Reihe von Konsolenbefehle in app/Console/Kernel.php registriert. Mein Kernel.php aussieht,Laravel benutzerdefinierte Konsole Befehl Aufruf Konstruktor aller anderen benutzerdefinierten Befehle

<?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 
    } 
} 

Die Struktur der Konsole Befehlsklasse wie

<?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 
    } 
} 

Jetzt ist das Problem aussieht, ist, wenn ich eine der Konsolenbefehle aus der Liste ausführen, der Konstruktor der andere wird auch mit dem tatsächlich ausgeführten ausgeführt.

Zum Beispiel, wenn ich "php artisan console_command_1" ausführen, wird der Konstruktor von beiden "php artisan console_command_1" und "php artisan console_command_2" ausgeführt und umgekehrt. Ich möchte eigentlich nur den Konstruktor des 'tatsächlich ausgeführten Handwerkerbefehls' aufrufen.

Ist das der Weg Laravel Konsole Befehl entworfen oder mache ich etwas falsch? Jede Hilfe wird sehr geschätzt.

Antwort

10

Ja, leider ist dies die einzige Möglichkeit für Laravel festzustellen, ob ein Handwerkerbefehl existiert oder nicht. Hier sind die beiden wichtigsten Dinge, die passieren, wenn Sie einen Befehl ausführen:

1. Wenn Sie einen Konsolenbefehl ausführen, der Einstiegspunkt ist die artisan Datei im Root Ihres Projekts befindet. Das erzeugt eine Kernel-Instanz und calls the handle method on it, die die empfangenen Argumente weitergibt (die sind: der Handwerker-Befehlsname und alle zusätzlichen Argumente, die dafür übergeben wurden).

2. Die handle der Kernel-Methode wird run the artisan command und um das zu tun, dass es a console application instance benötigen (intern, die als Artisan identifiziert wird), die resolveCommands müssen rufen eine Liste von Befehlen zu erstellen, so dass es, wenn überprüfen Der aktuelle Befehlsname ist gültig. Diese Methode wird make a new instance von jeden Befehl, die mit dem Kernel registriert ist (die Sie definiert, sowie alle Standard-geladenen aus der ArtisanServiceProvider).


Also wirklich, da in der Kernel Sie den Befehl über einen Klassennamen Referenz sind registriert:

Commands\ConsoleCommand1::class 

Und der Befehlsname ist eine geschützte Eigenschaft dieser Klasse:

protected $signature = ‘console_command_1’; 

Die einzige Möglichkeit, einen Befehlsnamen von einer Klasse abzurufen, besteht darin, eine Instanz dieser Klasse zu erstellen. Daher werden alle Konstruktoren für die gesamte zu erstellende Befehlsliste aufgerufen.

+0

Wirklich interessante Sachen. Danke für die klare Antwort @Bogdan. –

+0

Es ist lustig, dass die Dokumentation ein Beispiel mit einem Konstruktor zeigt, aber keine Warnung über seine Verwendung. Es scheint so, als ob die Signaturen im assoc-Array in den Kernel verschoben werden sollten. – jminkler

+0

Also, wenn es 10 Konsolenbefehlsklassen gibt, wird Laravel weiterhin die Klassen erstellen? Denn in meinem Fall erhalte ich alle 10 Sekunden Protokolle von den Konstruktoren der Befehle. Komisch, dass ich es jetzt bemerkt habe. – Farveaz

Verwandte Themen