- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
425 lines
11 KiB
Markdown
425 lines
11 KiB
Markdown
# Validation Framework Beispiele
|
|
|
|
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Validation Frameworks korrekt dar.
|
|
|
|
## Übersicht
|
|
|
|
Diese Dokumentation enthält praktische Beispiele für die Verwendung des Validation Frameworks in verschiedenen Szenarien. Die Beispiele zeigen, wie Sie Validierungsregeln auf Objekteigenschaften anwenden, Validierungsergebnisse verarbeiten und das Framework in verschiedenen Kontexten integrieren können.
|
|
|
|
## Grundlegende Verwendung
|
|
|
|
### Einfache Objektvalidierung
|
|
|
|
```php
|
|
use App\Framework\Validation\Rules\Required;
|
|
use App\Framework\Validation\Rules\Email;
|
|
use App\Framework\Validation\Rules\StringLength;
|
|
|
|
// 1. Definieren Sie eine Klasse mit Validierungsregeln
|
|
class UserData
|
|
{
|
|
#[Required]
|
|
#[StringLength(min: 3, max: 50)]
|
|
public string $name;
|
|
|
|
#[Required]
|
|
#[Email]
|
|
public string $email;
|
|
|
|
#[StringLength(max: 500)]
|
|
public ?string $bio = null;
|
|
}
|
|
|
|
// 2. Erstellen Sie eine Instanz der Klasse
|
|
$userData = new UserData();
|
|
$userData->name = 'Max Mustermann';
|
|
$userData->email = 'max@example.com';
|
|
|
|
// 3. Validieren Sie das Objekt
|
|
$validator = $container->get(Validator::class);
|
|
$result = $validator->validate($userData);
|
|
|
|
// 4. Überprüfen Sie das Ergebnis
|
|
if ($result->hasErrors()) {
|
|
// Fehlerbehandlung
|
|
$errors = $result->getAllErrorMessages();
|
|
foreach ($errors as $error) {
|
|
echo $error . "\n";
|
|
}
|
|
} else {
|
|
// Erfolgreiche Validierung
|
|
echo "Validierung erfolgreich!";
|
|
}
|
|
```
|
|
|
|
### Validierung mit benutzerdefinierten Fehlermeldungen
|
|
|
|
```php
|
|
class ProductData
|
|
{
|
|
#[Required(message: "Der Produktname ist erforderlich.")]
|
|
#[StringLength(min: 3, max: 100, message: "Der Produktname muss zwischen 3 und 100 Zeichen lang sein.")]
|
|
public string $name;
|
|
|
|
#[Required(message: "Der Preis ist erforderlich.")]
|
|
#[Range(min: 0, message: "Der Preis muss größer oder gleich 0 sein.")]
|
|
public float $price;
|
|
|
|
#[Required(message: "Die Kategorie ist erforderlich.")]
|
|
#[In(values: ['electronics', 'books', 'clothing'], message: "Ungültige Kategorie.")]
|
|
public string $category;
|
|
}
|
|
```
|
|
|
|
### Zugriff auf feldspezifische Fehler
|
|
|
|
```php
|
|
$result = $validator->validate($userData);
|
|
|
|
if ($result->hasErrors()) {
|
|
// Alle Fehler für ein bestimmtes Feld abrufen
|
|
$emailErrors = $result->getFieldErrors('email');
|
|
foreach ($emailErrors as $error) {
|
|
echo "Fehler im Feld 'email': $error\n";
|
|
}
|
|
|
|
// Alle Fehler nach Feld gruppiert abrufen
|
|
$allErrors = $result->getAll();
|
|
foreach ($allErrors as $field => $errors) {
|
|
echo "Fehler im Feld '$field':\n";
|
|
foreach ($errors as $error) {
|
|
echo "- $error\n";
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Fortgeschrittene Verwendung
|
|
|
|
### Validierungsgruppen
|
|
|
|
Validierungsgruppen ermöglichen es, verschiedene Validierungsszenarien für dasselbe Objekt zu definieren:
|
|
|
|
```php
|
|
use App\Framework\Validation\Rules\Required;
|
|
use App\Framework\Validation\Rules\Email;
|
|
use App\Framework\Validation\Rules\StringLength;
|
|
|
|
class UserProfile
|
|
{
|
|
#[Required(groups: ['registration', 'profile'])]
|
|
#[StringLength(min: 3, max: 50)]
|
|
public string $name;
|
|
|
|
#[Required(groups: ['registration'])]
|
|
#[Email]
|
|
public string $email;
|
|
|
|
#[Required(groups: ['profile'])]
|
|
#[StringLength(max: 500)]
|
|
public ?string $bio = null;
|
|
|
|
#[Required(groups: ['profile'])]
|
|
#[Url]
|
|
public ?string $website = null;
|
|
}
|
|
|
|
// Validierung mit einer bestimmten Gruppe
|
|
$result = $validator->validate($userProfile, 'registration');
|
|
|
|
// In diesem Fall werden nur die Regeln angewendet, die zur Gruppe 'registration' gehören
|
|
// oder keine Gruppe spezifiziert haben
|
|
```
|
|
|
|
### Verschachtelte Validierung
|
|
|
|
Validierung von Objekten, die andere validierbare Objekte enthalten:
|
|
|
|
```php
|
|
use App\Framework\Validation\Rules\Required;
|
|
use App\Framework\Validation\Rules\Email;
|
|
|
|
class Address
|
|
{
|
|
#[Required]
|
|
#[StringLength(min: 3, max: 100)]
|
|
public string $street;
|
|
|
|
#[Required]
|
|
#[StringLength(min: 3, max: 50)]
|
|
public string $city;
|
|
|
|
#[Required]
|
|
#[StringLength(min: 5, max: 10)]
|
|
public string $zipCode;
|
|
}
|
|
|
|
class Customer
|
|
{
|
|
#[Required]
|
|
#[StringLength(min: 3, max: 50)]
|
|
public string $name;
|
|
|
|
#[Required]
|
|
#[Email]
|
|
public string $email;
|
|
|
|
#[Required]
|
|
public Address $address;
|
|
}
|
|
|
|
// Validierung eines Objekts mit verschachtelten Objekten
|
|
$address = new Address();
|
|
$address->street = 'Musterstraße 123';
|
|
$address->city = 'Berlin';
|
|
$address->zipCode = '10115';
|
|
|
|
$customer = new Customer();
|
|
$customer->name = 'Max Mustermann';
|
|
$customer->email = 'max@example.com';
|
|
$customer->address = $address;
|
|
|
|
// Validierung des Hauptobjekts
|
|
$result = $validator->validate($customer);
|
|
|
|
// Manuelle Validierung des verschachtelten Objekts
|
|
$addressResult = $validator->validate($customer->address);
|
|
$result->merge($addressResult); // Kombinieren der Ergebnisse
|
|
```
|
|
|
|
### Benutzerdefinierte Validierungslogik
|
|
|
|
Verwendung der `Custom`-Regel für komplexe Validierungsanforderungen:
|
|
|
|
```php
|
|
use App\Framework\Validation\Rules\Custom;
|
|
use App\Framework\Validation\Rules\Required;
|
|
|
|
class PasswordReset
|
|
{
|
|
#[Required]
|
|
public string $email;
|
|
|
|
#[Required]
|
|
public string $password;
|
|
|
|
#[Required]
|
|
#[Custom(callback: 'validatePasswordConfirmation', message: "Die Passwörter stimmen nicht überein.")]
|
|
public string $passwordConfirmation;
|
|
|
|
private function validatePasswordConfirmation($value): bool
|
|
{
|
|
return $value === $this->password;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Integration mit Formularen
|
|
|
|
### Formularvalidierung
|
|
|
|
Verwendung des Validation Frameworks zur Validierung von Formulardaten:
|
|
|
|
```php
|
|
use App\Framework\Validation\ValidationFormHandler;
|
|
use App\Framework\Http\Response;
|
|
|
|
class UserController
|
|
{
|
|
public function handleRegistration(
|
|
Request $request,
|
|
ValidationFormHandler $formHandler,
|
|
UserService $userService
|
|
): Response {
|
|
// Formulardaten abrufen
|
|
$formData = $request->getFormData();
|
|
|
|
// Validierung durchführen
|
|
$result = $formHandler->validate(UserRegistration::class, $formData);
|
|
|
|
if ($result->hasErrors()) {
|
|
// Formular mit Fehlern neu rendern
|
|
return $this->renderForm('registration', [
|
|
'errors' => $result->getAll(),
|
|
'data' => $formData
|
|
]);
|
|
}
|
|
|
|
// Erfolgreiche Validierung, Benutzer registrieren
|
|
$userService->registerUser($formData);
|
|
|
|
// Weiterleitung zur Erfolgsseite
|
|
return $this->redirect('/registration/success');
|
|
}
|
|
}
|
|
```
|
|
|
|
### Formularvorlage mit Fehleranzeige
|
|
|
|
```html
|
|
<form method="post" action="/register">
|
|
<div class="form-group">
|
|
<label for="name">Name:</label>
|
|
<input type="text" id="name" name="name" value="<?= htmlspecialchars($data['name'] ?? '') ?>">
|
|
<?php if (isset($errors['name'])): ?>
|
|
<div class="error">
|
|
<?= htmlspecialchars($errors['name'][0]) ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="email">E-Mail:</label>
|
|
<input type="email" id="email" name="email" value="<?= htmlspecialchars($data['email'] ?? '') ?>">
|
|
<?php if (isset($errors['email'])): ?>
|
|
<div class="error">
|
|
<?= htmlspecialchars($errors['email'][0]) ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="password">Passwort:</label>
|
|
<input type="password" id="password" name="password">
|
|
<?php if (isset($errors['password'])): ?>
|
|
<div class="error">
|
|
<?= htmlspecialchars($errors['password'][0]) ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<button type="submit">Registrieren</button>
|
|
</form>
|
|
```
|
|
|
|
## API-Validierung
|
|
|
|
### Middleware für API-Validierung
|
|
|
|
Das Framework bietet eine `InputValidationMiddleware` für die automatische Validierung von API-Anfragen:
|
|
|
|
```php
|
|
// In der Bootstrap-Datei oder Router-Konfiguration
|
|
$app->addMiddleware(InputValidationMiddleware::class);
|
|
```
|
|
|
|
Konfiguration in `config/validation.php`:
|
|
|
|
```php
|
|
return [
|
|
'routes' => [
|
|
'/api/users' => [
|
|
'POST' => UserCreateData::class,
|
|
'PUT' => UserUpdateData::class
|
|
],
|
|
'/api/products' => [
|
|
'POST' => ProductCreateData::class,
|
|
'PUT' => ProductUpdateData::class
|
|
]
|
|
]
|
|
];
|
|
```
|
|
|
|
### API-Controller mit Validierung
|
|
|
|
```php
|
|
class ApiController
|
|
{
|
|
public function createUser(Request $request): Response
|
|
{
|
|
// Die Validierung wurde bereits durch die Middleware durchgeführt
|
|
// Wenn wir hier sind, waren die Daten gültig
|
|
|
|
$userData = $request->getJsonData();
|
|
$user = $this->userService->createUser($userData);
|
|
|
|
return new Response(201, [], [
|
|
'success' => true,
|
|
'user' => $user->toArray()
|
|
]);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Fehlerbehandlung für API-Validierung
|
|
|
|
Die `InputValidationMiddleware` gibt automatisch eine Fehlerantwort zurück, wenn die Validierung fehlschlägt:
|
|
|
|
```json
|
|
{
|
|
"error": "Validation failed",
|
|
"validation_errors": {
|
|
"name": ["Der Name ist erforderlich."],
|
|
"email": ["Bitte geben Sie eine gültige E-Mail-Adresse ein."]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Leistungsoptimierung
|
|
|
|
### Validierungs-Cache
|
|
|
|
Für häufig validierte Objekte kann ein Cache verwendet werden, um die Leistung zu verbessern:
|
|
|
|
```php
|
|
use App\Framework\Validation\ValidationCacheDecorator;
|
|
|
|
// Cache-Decorator erstellen
|
|
$cachedValidator = new ValidationCacheDecorator($validator, $cache);
|
|
|
|
// Validierung mit Cache durchführen
|
|
$result = $cachedValidator->validate($userData);
|
|
```
|
|
|
|
### Validierungsgruppen für partielle Validierung
|
|
|
|
Verwenden Sie Validierungsgruppen, um nur die relevanten Teile eines Objekts zu validieren:
|
|
|
|
```php
|
|
// Nur die für die Aktualisierung relevanten Felder validieren
|
|
$result = $validator->validate($userData, 'update');
|
|
```
|
|
|
|
## Fehlerbehebung
|
|
|
|
### Häufige Probleme und Lösungen
|
|
|
|
#### Validierungsregeln werden nicht angewendet
|
|
|
|
Stellen Sie sicher, dass:
|
|
- Die Attribute korrekt definiert sind
|
|
- Die Eigenschaften für den Validator zugänglich sind (public oder mit Reflection)
|
|
- Der Validator korrekt initialisiert wurde
|
|
|
|
```php
|
|
// Korrekte Initialisierung des Validators
|
|
$validator = new Validator($reflectionProvider);
|
|
```
|
|
|
|
#### Falsche Fehlermeldungen
|
|
|
|
Überprüfen Sie die Reihenfolge der Validierungsregeln:
|
|
|
|
```php
|
|
// Korrekte Reihenfolge: Required vor anderen Regeln
|
|
#[Required]
|
|
#[Email]
|
|
public string $email;
|
|
```
|
|
|
|
#### Leistungsprobleme
|
|
|
|
Verwenden Sie den ValidationCacheDecorator und vermeiden Sie zu komplexe Validierungsregeln:
|
|
|
|
```php
|
|
// Einfache Regeln verwenden
|
|
#[StringLength(max: 255)] // Besser als komplexe reguläre Ausdrücke
|
|
public string $name;
|
|
```
|
|
|
|
## Weiterführende Informationen
|
|
|
|
- [Validation Framework Übersicht](index.md)
|
|
- [Verfügbare Validierungsregeln](rules.md)
|
|
- [API-Validierung](/guides/api-validation.md)
|