Zum Hauptinhalt springen

Was ist GeneratorCommand?

Illuminate\Console\GeneratorCommand ist die abstrakte Basisklasse aller Code-Generierungs-Befehle in Laravel. make:model, make:controller, make:request usw. leiten alle von dieser Klasse ab. Bietet ein Paket einen eigenen make:xxx-Befehl an, so muss der Nutzer keine Klassen von Hand anlegen. Ein php artisan make:handler OrderHandler genügt, um eine Datei mit korrektem Namensraum zu erzeugen.
GeneratorCommand wird in der offiziellen Doku kaum erwähnt und ist ohne Blick in den Framework-Code kaum zu verstehen — ein klassisches Advanced-Thema.

Minimale Implementierung

Die einzig zwingend erforderliche Methode in einer von GeneratorCommand abgeleiteten Klasse ist getStub(). Alle anderen Properties sind optional, in der Praxis definiert man aber typischerweise diese:
ElementTypRolle
$namePropertyKommandoname (z. B. make:handler)
$descriptionPropertyBeschreibung des Befehls
$typePropertyBezeichnung des Artefakts — erscheint in der Erfolgsmeldung (z. B. Handler)
getStub()Methode (Pflicht)Gibt den Pfad zur Stub-Datei zurück
getDefaultNamespace()MethodeSteuert den Ziel-Namensraum
Beispielhafte Implementierung eines make:handler-Befehls:
<?php

namespace Vendor\Package\Console\Commands;

use Illuminate\Console\GeneratorCommand;

class HandlerMakeCommand extends GeneratorCommand
{
    protected $name = 'make:handler';

    protected $description = 'Create a new handler class';

    protected $type = 'Handler';

    protected function getStub(): string
    {
        return __DIR__.'/stubs/handler.stub';
    }

    protected function getDefaultNamespace($rootNamespace): string
    {
        return $rootNamespace.'\Handlers';
    }
}
Mit dieser Konfiguration von getDefaultNamespace() legt php artisan make:handler OrderHandler die Klasse App\Handlers\OrderHandler in app/Handlers/OrderHandler.php an.

Stub-Datei erstellen

Legen Sie eine Stub-Datei an dem Pfad ab, den getStub() zurückgibt. Ein Stub ist eine PHP-Vorlage, in der Platzhalter für Namensraum und Klassennamen ersetzt werden.
src
Console
Commands
HandlerMakeCommand.php
stubs
handler.stub
Beispiel für eine Stub-Datei:
handler.stub
<?php

namespace {{ namespace }};

class {{ class }}
{
    public function handle(): void
    {
        //
    }
}
GeneratorCommand ersetzt in Stubs automatisch folgende Platzhalter:
PlatzhalterErsetzter WertAlternative Notation
{{ namespace }}Namensraum der erzeugten KlasseDummyNamespace
{{ class }}Name der erzeugten KlasseDummyClass
{{ rootNamespace }}Root-Namensraum der AppDummyRootNamespace
{{ namespace }} und DummyNamespace liefern das gleiche Ergebnis. In den Laravel-Stubs sind beide Formen enthalten; für neue Stubs empfehlen wir die Form {{ namespace }}.

Stubs anpassbar machen

Um Nutzern zu erlauben, die Stubs zu überschreiben, nutzen Sie das resolveStubPath()-Muster. Zunächst veröffentlichen Sie die Stubs im boot() des Service Providers.
public function boot(): void
{
    if ($this->app->runningInConsole()) {
        $this->publishes([
            __DIR__.'/../Console/Commands/stubs' => base_path('stubs'),
        ], 'stubs');
    }
}
Danach lassen Sie getStub() das vom Nutzer angepasste Stub bevorzugt verwenden.
protected function getStub(): string
{
    return $this->resolveStubPath('/stubs/handler.stub');
}

protected function resolveStubPath(string $stub): string
{
    return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
        ? $customPath
        : __DIR__.$stub;
}
Nach php artisan vendor:publish --tag=stubs bearbeiten Nutzer die Datei stubs/handler.stub im Projekt-Root und passen so die Vorlage an.
resolveStubPath() ist auch das Muster, das der eingebaute RequestMakeCommand nutzt. Übernehmen Sie es für veröffentlichte Pakete.

Registrierung im Service Provider

Registrieren Sie den Befehl in der boot()-Methode Ihres Service Providers. Mit runningInConsole() verhindern Sie unnötiges Laden bei Web-Requests.
<?php

namespace Vendor\Package;

use Illuminate\Support\ServiceProvider;
use Vendor\Package\Console\Commands\HandlerMakeCommand;

class PackageServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if ($this->app->runningInConsole()) {
            $this->commands([
                HandlerMakeCommand::class,
            ]);

            $this->publishes([
                __DIR__.'/../Console/Commands/stubs' => base_path('stubs'),
            ], 'stubs');
        }
    }
}
Mit extra.laravel in der composer.json Ihres Pakets müssen Nutzer den Provider nicht selbst registrieren.
"extra": {
    "laravel": {
        "providers": [
            "Vendor\\Package\\PackageServiceProvider"
        ]
    }
}

Anwendungsbeispiele

Wo GeneratorCommand glänzt:
Ein Befehl, der Requests erzeugt, die von einer eigenen Basisklasse mit Auth-Prüfung und eigener Validierung erben. getDefaultNamespace() liefert App\Http\Requests.
Ein Befehl, der Boilerplate für Data Transfer Objects erzeugt. Der Stub enthält readonly-Properties und eine from()-Factory-Methode.
Ein Befehl, der Action-Klassen mit einer einzigen Verantwortlichkeit erzeugt. Er legt Klassen mit execute()-Methode im Namensraum App\Actions an.
Der Befehl make:livewire ist als MakeCommand-Klasse implementiert, die von GeneratorCommand erbt. Um sowohl Komponentenklasse als auch Blade-View zu erzeugen, überschreibt sie handle().

Tests

Mit Orchestra Testbench testen Sie, dass Ihr Befehl die Dateien korrekt erzeugt.
<?php

namespace Tests\Feature\Console;

use Illuminate\Support\Facades\File;
use Orchestra\Testbench\TestCase;
use Vendor\Package\PackageServiceProvider;

class HandlerMakeCommandTest extends TestCase
{
    protected function getPackageProviders($app): array
    {
        return [PackageServiceProvider::class];
    }

    protected function tearDown(): void
    {
        File::deleteDirectory(app_path('Handlers'));

        parent::tearDown();
    }

    public function test_make_handler_creates_file(): void
    {
        $path = app_path('Handlers/OrderHandler.php');

        $this->artisan('make:handler', ['name' => 'OrderHandler'])
            ->assertSuccessful();

        $this->assertFileExists($path);
        $this->assertStringContainsString('namespace App\Handlers;', File::get($path));
        $this->assertStringContainsString('class OrderHandler', File::get($path));
    }

    public function test_make_handler_does_not_overwrite_existing_file(): void
    {
        $path = app_path('Handlers/OrderHandler.php');
        File::ensureDirectoryExists(dirname($path));
        File::put($path, '<?php // existing');

        $this->artisan('make:handler', ['name' => 'OrderHandler'])
            ->assertFailed();
    }
}
Generator-Commands schreiben tatsächlich ins Dateisystem. Räumen Sie in tearDown() konsequent auf, damit auch bei fehlgeschlagenen Tests aufgeräumt wird.

Verwandte Seiten

Laravel-Paketentwicklung

Grundlagen der Paketentwicklung mit Service Providern.

Laravel-Pakete mit Orchestra Testbench testen

Wie Sie die Grundlagen für Pakettests schaffen.
Zuletzt geändert am 13. Juli 2026