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
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

370
docs/guides/routing.md Normal file
View File

@@ -0,0 +1,370 @@
# 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.