Files
michaelschiemer/docs/guides/routing.md
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

11 KiB

Routing-Anleitung

Diese Anleitung erklärt, wie das Routing-System des Frameworks funktioniert und wie Sie es effektiv nutzen können.

Grundlagen des Routings

Das Routing-System ist verantwortlich für das Mapping von HTTP-Anfragen zu Controller-Aktionen. Es ermöglicht Ihnen, URLs zu definieren und festzulegen, welcher Code ausgeführt werden soll, wenn diese URLs aufgerufen werden.

Routing-Konfiguration

Die Routing-Konfiguration befindet sich in der Datei config/routes.php. Diese Datei gibt eine Funktion zurück, die einen Router als Parameter erhält:

<?php

use App\Framework\Routing\Router;
use App\Application\Controllers\HomeController;
use App\Application\Controllers\UserController;

return function (Router $router) {
    // Hier werden Routen definiert
    $router->get('/', [HomeController::class, 'index']);
    $router->get('/users', [UserController::class, 'index']);
    $router->get('/users/{id}', [UserController::class, 'show']);
};

Definieren von Routen

Grundlegende Routen

Sie können Routen für verschiedene HTTP-Methoden definieren:

// GET-Route
$router->get('/users', [UserController::class, 'index']);

// POST-Route
$router->post('/users', [UserController::class, 'store']);

// PUT-Route
$router->put('/users/{id}', [UserController::class, 'update']);

// PATCH-Route
$router->patch('/users/{id}', [UserController::class, 'update']);

// DELETE-Route
$router->delete('/users/{id}', [UserController::class, 'destroy']);

// Mehrere HTTP-Methoden
$router->match(['GET', 'POST'], '/users/search', [UserController::class, 'search']);

// Alle HTTP-Methoden
$router->any('/users/all', [UserController::class, 'all']);

Routenparameter

Sie können dynamische Segmente in Ihren Routen definieren, indem Sie geschweifte Klammern verwenden:

$router->get('/users/{id}', [UserController::class, 'show']);
$router->get('/posts/{post}/comments/{comment}', [CommentController::class, 'show']);

Diese Parameter werden automatisch an die Controller-Methode übergeben:

public function show(Request $request, int $id): Response
{
    $user = User::find($id);
    // ...
}

public function show(Request $request, int $post, int $comment): Response
{
    $post = Post::find($post);
    $comment = Comment::find($comment);
    // ...
}

Optionale Parameter

Sie können optionale Parameter definieren, indem Sie ein Fragezeichen nach dem Parameternamen hinzufügen:

$router->get('/users/{id?}', [UserController::class, 'show']);

In diesem Fall müssen Sie in Ihrer Controller-Methode einen Standardwert für den Parameter angeben:

public function show(Request $request, int $id = null): Response
{
    if ($id === null) {
        // Alle Benutzer anzeigen
    } else {
        // Einen bestimmten Benutzer anzeigen
    }
    // ...
}

Parametereinschränkungen

Sie können Einschränkungen für Routenparameter definieren, um sicherzustellen, dass sie einem bestimmten Muster entsprechen:

$router->get('/users/{id}', [UserController::class, 'show'])
    ->where('id', '[0-9]+');

$router->get('/posts/{slug}', [PostController::class, 'show'])
    ->where('slug', '[a-z0-9-]+');

$router->get('/categories/{category}/posts/{post}', [PostController::class, 'showInCategory'])
    ->where(['category' => '[a-z0-9-]+', 'post' => '[0-9]+']);

Benannte Routen

Sie können Routen benennen, um später einfacher auf sie verweisen zu können:

$router->get('/users/{id}', [UserController::class, 'show'])
    ->name('users.show');

Sie können dann URLs für benannte Routen generieren:

$url = route('users.show', ['id' => 1]); // /users/1

Routengruppen

Routengruppen ermöglichen es Ihnen, gemeinsame Attribute auf mehrere Routen anzuwenden, ohne sie für jede Route einzeln definieren zu müssen.

Präfixe

Sie können ein Präfix für eine Gruppe von Routen definieren:

$router->group('/admin', function (Router $router) {
    $router->get('/dashboard', [AdminController::class, 'dashboard']);
    $router->get('/users', [AdminController::class, 'users']);
    $router->get('/settings', [AdminController::class, 'settings']);
});

Dies definiert die folgenden Routen:

  • /admin/dashboard
  • /admin/users
  • /admin/settings

Middleware

Sie können Middleware für eine Gruppe von Routen definieren:

$router->group('', function (Router $router) {
    $router->get('/dashboard', [AdminController::class, 'dashboard']);
    $router->get('/users', [AdminController::class, 'users']);
    $router->get('/settings', [AdminController::class, 'settings']);
})->middleware(AuthMiddleware::class);

Sie können auch mehrere Middleware-Klassen angeben:

$router->group('', function (Router $router) {
    // Routen
})->middleware([AuthMiddleware::class, AdminMiddleware::class]);

Namensräume

Sie können einen Namensraum für eine Gruppe von Routen definieren:

$router->group('', function (Router $router) {
    $router->get('/users', ['UserController', 'index']);
    $router->get('/posts', ['PostController', 'index']);
})->namespace('App\\Application\\Controllers\\Admin');

In diesem Fall werden die Controller-Klassen im Namensraum App\Application\Controllers\Admin gesucht, also App\Application\Controllers\Admin\UserController und App\Application\Controllers\Admin\PostController.

Kombinierte Attribute

Sie können mehrere Attribute für eine Gruppe von Routen kombinieren:

$router->group('/admin', function (Router $router) {
    $router->get('/dashboard', ['DashboardController', 'index']);
    $router->get('/users', ['UserController', 'index']);
})
    ->namespace('App\\Application\\Controllers\\Admin')
    ->middleware([AuthMiddleware::class, AdminMiddleware::class])
    ->name('admin.');

Dies definiert die folgenden Routen:

  • /admin/dashboard mit dem Namen admin.dashboard
  • /admin/users mit dem Namen admin.users

Beide Routen verwenden die Controller im Namensraum App\Application\Controllers\Admin und durchlaufen die AuthMiddleware und AdminMiddleware.

Verschachtelte Gruppen

Sie können Routengruppen verschachteln, um komplexere Strukturen zu erstellen:

$router->group('/admin', function (Router $router) {
    $router->get('/dashboard', [AdminController::class, 'dashboard']);
    
    $router->group('/users', function (Router $router) {
        $router->get('/', [AdminUserController::class, 'index']);
        $router->get('/{id}', [AdminUserController::class, 'show']);
        $router->put('/{id}', [AdminUserController::class, 'update']);
        $router->delete('/{id}', [AdminUserController::class, 'destroy']);
    });
    
    $router->group('/settings', function (Router $router) {
        $router->get('/', [AdminSettingsController::class, 'index']);
        $router->put('/general', [AdminSettingsController::class, 'updateGeneral']);
        $router->put('/security', [AdminSettingsController::class, 'updateSecurity']);
    });
});

Fallback-Routen

Sie können eine Fallback-Route definieren, die verwendet wird, wenn keine andere Route übereinstimmt:

$router->fallback([NotFoundController::class, 'index']);

Middleware für einzelne Routen

Sie können Middleware auch für einzelne Routen definieren:

$router->get('/profile', [ProfileController::class, 'index'])
    ->middleware(AuthMiddleware::class);

$router->get('/admin/dashboard', [AdminController::class, 'dashboard'])
    ->middleware([AuthMiddleware::class, AdminMiddleware::class]);

Routen-Caching

Um die Leistung zu verbessern, können Sie die Routing-Konfiguration cachen:

php console.php route:cache

Dies erstellt eine Cache-Datei, die vom Framework verwendet wird, anstatt die Routen bei jeder Anfrage neu zu analysieren.

Um den Cache zu löschen:

php console.php route:clear

Routen auflisten

Sie können alle registrierten Routen auflisten:

php console.php route:list

Dies zeigt eine Tabelle mit allen Routen, ihren HTTP-Methoden, URLs, Controller-Aktionen und Namen an.

Routen-Modell-Binding

Das Framework unterstützt Routen-Modell-Binding, das automatisch Modellinstanzen aus Routenparametern auflöst:

$router->get('/users/{user}', [UserController::class, 'show']);

In Ihrem Controller:

public function show(Request $request, User $user): Response
{
    // $user ist bereits eine Instanz des User-Modells
    return $this->view('users.show', ['user' => $user]);
}

Standardmäßig wird der Parameter {user} als ID verwendet, um das Modell zu finden. Sie können dieses Verhalten anpassen, indem Sie die Methode resolveRouteBinding in Ihrem Modell überschreiben:

public function resolveRouteBinding(string $value): ?static
{
    return static::where('username', $value)->first();
}

Ressourcen-Routen

Das Framework bietet eine Möglichkeit, schnell Ressourcen-Routen für CRUD-Operationen zu definieren:

$router->resource('photos', PhotoController::class);

Dies erstellt die folgenden Routen:

HTTP-Methode URI Aktion Routenname
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

Sie können die generierten Routen einschränken:

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

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

API-Ressourcen-Routen

Für APIs können Sie API-Ressourcen-Routen definieren, die keine create und edit Routen enthalten:

$router->apiResource('photos', PhotoApiController::class);

Dies erstellt die folgenden Routen:

HTTP-Methode URI Aktion Routenname
GET /photos index photos.index
POST /photos store photos.store
GET /photos/{photo} show photos.show
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

Verschachtelte Ressourcen

Sie können auch verschachtelte Ressourcen definieren:

$router->resource('photos.comments', PhotoCommentController::class);

Dies erstellt Routen wie:

  • /photos/{photo}/comments
  • /photos/{photo}/comments/{comment}

Weitere Informationen