Zum Hauptinhalt springen
Mit Laravel 11 wurde die Anwendungsstruktur als „Slim Application Skeleton” grundlegend überarbeitet. Wer in einem Projekt mit alter Struktur eingestiegen ist oder mit Laravel 10 und älteren Büchern gelernt hat, stolpert an denselben Stellen. Wir sammeln hier die Fragen, die in Laracasts-Foren und auf Stack Overflow rund um das Release von Laravel 11 besonders häufig gestellt wurden.
Dieses FAQ richtet sich an neue Projekte (Laravel 11 oder höher). Die Migration eines bestehenden Projekts wird im Migrationsleitfaden beschrieben.
In der neuen Struktur werden selten geänderte Config-Dateien aus dem Projekt entfernt. Verwendet werden dann die Dateien im Framework-eigenen config/.Projekt- und Framework-config/ werden gemergt, wobei die Projekt-Seite Vorrang hat. Sobald Anpassungen nötig sind, legen Sie die Datei einfach an — sie wird berücksichtigt.
# Config-Datei im Framework anschauen
cat vendor/laravel/framework/config/cors.php

# In das Projekt kopieren und anpassen
php artisan config:publish cors
In der neuen Struktur von Laravel 11 ist App\Http\Controllers\Controller eine leere Klasse. Sie erbt nicht mehr von Illuminate\Routing\Controller und verwendet weder ValidatesRequests noch AuthorizesRequests.
Laravel 10Laravel 11
Erbt von Illuminate\Routing\ControllerLeere Klasse
Nutzt Trait ValidatesRequestsNein
Nutzt Trait AuthorizesRequestsNein
Referenz: Controller in Laravel 10 vs. Controller in Laravel 11Alternativen:
// $request->validate() verwenden
public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
    ]);
}

// Gate::authorize() verwenden
use Illuminate\Support\Facades\Gate;

public function update(Request $request, Post $post)
{
    Gate::authorize('update', $post);
}
Wenn Sie diese Methoden häufig brauchen, können Sie App\Http\Controllers\Controller wie in Laravel 10 wiederherstellen.
<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

abstract class Controller extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;
}
In der neuen Struktur entfällt app/Http/Kernel.php. Middleware konfigurieren Sie über withMiddleware() in bootstrap/app.php.
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    // Einstellungen der TrustProxies-Middleware und andere gehen alle über Methoden der Middleware-Klasse
    $middleware->trustProxies(at: '*');

    // Globale Middleware hinzufügen
    $middleware->append(\App\Http\Middleware\MyMiddleware::class);

    // Alias für Route-Gruppen
    $middleware->alias([
        'my-middleware' => \App\Http\Middleware\MyMiddleware::class,
    ]);

    // Web-/API-Middleware-Gruppen anpassen
    $middleware->web(append: [
        \App\Http\Middleware\HandleInertiaRequests::class,
    ]);
})
Die Middleware-Dateien selbst legen Sie weiterhin in app/Http/Middleware/ an.
$this->middleware() gehört zu Illuminate\Routing\Controller und ist im leeren Basiscontroller der neuen Struktur nicht verfügbar.Verwenden Sie stattdessen das Interface HasMiddleware und definieren Sie die Methode middleware().
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;

class UserController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            'auth',
            new Middleware('log', only: ['index']),
            new Middleware('subscribed', except: ['index']),
        ];
    }
}
Ab Laravel 13 gibt es zusätzlich das Attribut #[Middleware].
use Illuminate\Routing\Controllers\HasMiddleware;
use App\Http\Middleware\EnsureTokenIsValid;

#[Middleware(EnsureTokenIsValid::class)]
class UserController extends Controller
{
    // ...
}
Referenz: Controller-Middleware
authorizeResource() gehört zum Trait AuthorizesRequests und ist im leeren Basiscontroller der neuen Struktur nicht verfügbar.Es gibt mehrere Optionen.1. Basiscontroller wie in Laravel 10 wiederherstellen (am einfachsten)
// app/Http/Controllers/Controller.php
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Routing\Controller as BaseController;

abstract class Controller extends BaseController
{
    use AuthorizesRequests;
}
Damit steht $this->authorizeResource() wieder zur Verfügung.2. Das Laravel-13-Attribut #[Authorize] an jeder Methode einsetzen
use Illuminate\Routing\Attributes\Controllers\Authorize;
use App\Models\Post;

class PostController extends Controller
{
    #[Authorize('view', 'post')]
    public function show(Post $post) { /* ... */ }

    #[Authorize('update', 'post')]
    public function update(Request $request, Post $post) { /* ... */ }
}
In der neuen Struktur entfällt app/Console/Kernel.php; der Scheduler wird an anderer Stelle konfiguriert.In routes/console.php (empfohlen):
// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')->daily();
Schedule::job(new SendEmails)->everyFiveMinutes();
In bootstrap/app.php:
->withSchedule(function (Schedule $schedule) {
    $schedule->command('emails:send')->daily();
})
In der neuen Struktur entfällt der EventServiceProvider — Events und Listener müssen nicht mehr manuell registriert werden.Automatische Registrierung: Deklarieren Sie in der handle()-Methode des Listeners die Event-Klasse per Type-Hint — sie wird automatisch registriert.
namespace App\Listeners;

use App\Events\OrderShipped;

class SendShipmentNotification
{
    // Ein Type-Hint der Event-Klasse in handle() reicht für die automatische Registrierung
    public function handle(OrderShipped $event): void
    {
        // ...
    }
}
Manuelle Registrierung erfolgt in AppServiceProvider::boot().
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(
        OrderShipped::class,
        SendShipmentNotification::class,
    );
}
In der neuen Struktur wird die Provider-Liste nicht mehr in config/app.php, sondern in bootstrap/providers.php gepflegt.
// bootstrap/providers.php
return [
    App\Providers\AppServiceProvider::class,
    App\Providers\MyCustomServiceProvider::class, // ← hier ergänzen
];
Ein per artisan make:provider erzeugter Provider wird automatisch dort eingetragen.
In der neuen Struktur entfällt app/Exceptions/Handler.php. Ausnahmebehandlung konfigurieren Sie über withExceptions() in bootstrap/app.php.
// bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
    // Bestimmte Exceptions nicht melden
    $exceptions->dontReport(InvalidOrderException::class);

    // Eigenes Rendering
    $exceptions->render(function (InvalidOrderException $e, Request $request) {
        return response()->view('errors.invalid-order', status: 500);
    });

    // Weiterleitung bei nicht authentifizierten Nutzern anpassen
    $exceptions->shouldRenderJsonWhen(function (Request $request, Throwable $e) {
        return $request->is('api/*');
    });
})
Routing passen Sie über withRouting() in bootstrap/app.php an.Zusätzliche Route-Datei einbinden:
->withRouting(
    web: __DIR__.'/../routes/web.php',
    then: function () {
        Route::middleware('web')
            ->prefix('admin')
            ->group(base_path('routes/admin.php'));
    },
)
Vollständige Kontrolle (wie beim RouteServiceProvider in Laravel 10):Mit using deaktivieren Sie die Standard-Registrierung von Laravel vollständig und übernehmen alles selbst.
->withRouting(
    using: function () {
        Route::middleware('web')
            ->group(base_path('routes/web.php'));

        Route::middleware('api')
            ->prefix('api')
            ->group(base_path('routes/api.php'));
    },
)
Fügen Sie in config/app.php den Schlüssel providers ein — die Einstellung wird mit der Framework-Konfiguration gemergt.
// config/app.php
use Illuminate\Support\ServiceProvider;

return [
    // ...
    'providers' => ServiceProvider::defaultProviders()->replace([
        Illuminate\Foo\FooServiceProvider::class => Bar\BarServiceProvider::class,
    ])->toArray(),
];
Mit replace() tauschen Sie Standard-Provider durch eigene Implementierungen aus.
Ab Laravel 11 sind API-Funktionen standardmäßig nicht enthalten und werden bei Bedarf einzeln installiert.
php artisan install:api
Der Befehl legt bzw. konfiguriert:
  • routes/api.php
  • Einstellungen für Laravel Sanctum als API-Authentifizierung
  • Registrierung der API-Routen in bootstrap/app.php
Auch Broadcasting ist ab Laravel 11 standardmäßig nicht enthalten und wird bei Bedarf einzeln installiert.
php artisan install:broadcasting
Der Befehl legt bzw. konfiguriert:
  • routes/channels.php
  • Setup von Laravel Reverb
  • Broadcasting-Konfigurationsdateien
Schauen Sie in bootstrap/app.php.Neue Struktur ab Laravel 11 (oder bereits migriert):
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(...)
    ->withMiddleware(...)
    ->withExceptions(...)
    ->create();
Ein Projekt in alter Struktur, das nur auf die neue Version gehoben wurde:
// bootstrap/app.php
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);
// ...
Beginnt die Datei mit return Application::configure(...), ist es die neue Struktur — andernfalls ein Upgrade in alter Struktur. Die Migration zur neuen Struktur beschreibt der Migrationsleitfaden.

Verwandte Seiten

Anwendungsstruktur ab Laravel 11

Vollständige Erläuterung der neuen App-Struktur und der internen Implementierung des ApplicationBuilder.

Migrationsleitfaden von alter zu neuer Struktur

Schritt-für-Schritt-Anleitung zum Umstieg von Laravel 10 auf die neue Struktur ab Laravel 11.
Zuletzt geändert am 13. Juli 2026