- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
371 lines
11 KiB
Markdown
371 lines
11 KiB
Markdown
# 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
|
|
<?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:
|
|
|
|
```php
|
|
// 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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
$router->get('/users/{id?}', [UserController::class, 'show']);
|
|
```
|
|
|
|
In diesem Fall müssen Sie in Ihrer Controller-Methode einen Standardwert für den Parameter angeben:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$router->get('/users/{id}', [UserController::class, 'show'])
|
|
->name('users.show');
|
|
```
|
|
|
|
Sie können dann URLs für benannte Routen generieren:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$router->fallback([NotFoundController::class, 'index']);
|
|
```
|
|
|
|
## Middleware für einzelne Routen
|
|
|
|
Sie können Middleware auch für einzelne Routen definieren:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
php console.php route:clear
|
|
```
|
|
|
|
## Routen auflisten
|
|
|
|
Sie können alle registrierten Routen auflisten:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```php
|
|
$router->get('/users/{user}', [UserController::class, 'show']);
|
|
```
|
|
|
|
In Ihrem Controller:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$router->resource('photos.comments', PhotoCommentController::class);
|
|
```
|
|
|
|
Dies erstellt Routen wie:
|
|
- `/photos/{photo}/comments`
|
|
- `/photos/{photo}/comments/{comment}`
|
|
|
|
## Weitere Informationen
|
|
|
|
- [Controller-Anleitung](controllers.md): Erfahren Sie mehr über Controller und wie sie mit Routen interagieren.
|
|
- [Middleware-Anleitung](middleware.md): Erfahren Sie mehr über Middleware und wie sie im Routing-System verwendet werden.
|
|
- [Validierungs-Anleitung](validation.md): Erfahren Sie, wie Sie Benutzereingaben validieren können.
|
|
- [Architekturübersicht](../architecture/overview.md): Überblick über die Architektur des Frameworks.
|