Zum Hauptinhalt springen

Was ist ein Controller

Statt sämtliche Request-Verarbeitungslogik als Closures in Routendateien zu definieren, können Sie sie in „Controller”-Klassen organisieren. Ein Controller bündelt zusammengehörige Logik in einer Klasse. Ein UserController etwa kann alle eingehenden Anfragen zu Benutzern behandeln – Anzeigen, Anlegen, Aktualisieren, Löschen usw. Standardmäßig liegen Controller im Verzeichnis app/Http/Controllers.

Controller erstellen

Um schnell einen neuen Controller zu erzeugen, nutzen Sie den Artisan-Befehl make:controller. Alle Controller Ihrer Anwendung landen standardmäßig unter app/Http/Controllers.
php artisan make:controller UserController

Basis-Controller

Eine Controller-Klasse kann mehrere öffentliche Methoden besitzen, die auf eingehende HTTP-Anfragen reagieren.
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Profil des angegebenen Benutzers anzeigen
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
Nachdem Sie Klasse und Methode angelegt haben, verweisen Sie in der Route wie folgt auf sie:
use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);
Passt ein Request auf die URI, wird die Methode show von App\Http\Controllers\UserController aufgerufen und der Routenparameter an sie übergeben.
Controller müssen keine Basisklasse erweitern. Es kann aber praktisch sein, einen Basis-Controller zu haben, der gemeinsame Methoden bereitstellt.

Single Action Controller

Wenn eine Controller-Aktion besonders komplex ist, kann es sinnvoll sein, die ganze Klasse dieser einen Aktion zu widmen. Definieren Sie dazu eine einzige __invoke-Methode.
<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * Neuen Webserver bereitstellen
     */
    public function __invoke()
    {
        // ...
    }
}
In der Routenregistrierung für einen Single Action Controller müssen Sie keine Methode angeben – geben Sie nur den Klassennamen an.
use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);
Mit der Option --invokable erzeugt make:controller einen aufrufbaren Controller.
php artisan make:controller ProvisionServer --invokable

Resource-Controller

Wenn Sie sich Ihre Eloquent-Modelle als „Ressourcen” vorstellen, führen Sie für jede meist dieselben Operationen (CRUD) aus. Das Resource-Routing von Laravel weist die typischen CRUD-Routen einem Controller mit einer einzigen Zeile Code zu. Mit --resource erstellen Sie den passenden Controller.
php artisan make:controller PhotoController --resource
Der Befehl legt app/Http/Controllers/PhotoController.php an. Der Controller enthält Stubs für alle Aktionen einer Ressource. Anschließend registrieren Sie die Resource-Route.
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class);
Diese eine Zeile erzeugt mehrere Routen für die verschiedenen Aktionen. Die zugehörigen Methoden sind bereits im Controller vorhanden.
HTTP-MethodeURIAktionRoutenname
GET/photosindexphotos.index
GET/photos/createcreatephotos.create
POST/photosstorephotos.store
GET/photos/{photo}showphotos.show
GET/photos/{photo}/editeditphotos.edit
PUT/PATCH/photos/{photo}updatephotos.update
DELETE/photos/{photo}destroyphotos.destroy
Mit php artisan route:list erhalten Sie schnell einen Überblick über die Routen der Anwendung.

Teilweise Resource-Routen

Sie können festlegen, welche Aktionen der Controller behandeln soll.
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);

API-Resource-Routen

Bei APIs möchten Sie in der Regel keine Routen für HTML-Formulare wie create oder edit. Mit apiResource schließen Sie diese beiden Routen automatisch aus.
use App\Http\Controllers\PhotoController;

Route::apiResource('photos', PhotoController::class);

Dependency Injection

Constructor Injection

Der Service Container von Laravel löst alle Controller auf. Deshalb können Sie im Konstruktor Type Hints für benötigte Abhängigkeiten angeben. Sie werden automatisch aufgelöst und injiziert.
<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * Neue Controller-Instanz erzeugen
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}

Method Injection

Zusätzlich zur Constructor Injection können Sie Abhängigkeiten auch pro Methode per Type Hint deklarieren. Ein typisches Beispiel ist das Injizieren einer Illuminate\Http\Request-Instanz.
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Neuen Benutzer speichern
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->name;

        // Benutzer speichern...

        return redirect('/users');
    }
}
Nimmt Ihre Methode auch Routenparameter entgegen, listen Sie diese nach den anderen Abhängigkeiten. Angenommen, die Route ist so definiert:
use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);
Dann definieren Sie die Methode wie folgt, um Request und id zu verwenden.
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Angegebenen Benutzer aktualisieren
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // Benutzer aktualisieren...

        return redirect('/users');
    }
}
Durch Dependency Injection lassen sich in Tests problemlos Mocks einschleusen – die Testbarkeit Ihres Codes steigt.

Nächste Schritte

Routing

Frischen Sie das Definieren von Routen und die Anbindung an Controller auf.
Zuletzt geändert am 13. Juli 2026