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:
424
docs/components/validation/examples.md
Normal file
424
docs/components/validation/examples.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# 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)
|
||||
338
docs/components/validation/index.md
Normal file
338
docs/components/validation/index.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# Validation Framework
|
||||
|
||||
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Validation Frameworks korrekt dar.
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Validation Framework ist ein leistungsstarkes System zur Validierung von Objekten und Daten in der Anwendung. Es nutzt moderne PHP-Attribute, um Validierungsregeln direkt an Objekteigenschaften zu definieren, und bietet eine flexible, erweiterbare Architektur für verschiedene Validierungsanforderungen.
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Validator-Klasse
|
||||
|
||||
Die zentrale Klasse für die Validierungsfunktionalität:
|
||||
|
||||
```php
|
||||
// Klasse initialisieren
|
||||
$validator = new Validator($reflectionProvider);
|
||||
|
||||
// Objekt validieren
|
||||
$result = $validator->validate($object);
|
||||
|
||||
// Validierungsergebnis prüfen
|
||||
if ($result->hasErrors()) {
|
||||
// Fehlerbehandlung
|
||||
$errors = $result->getAllErrorMessages();
|
||||
}
|
||||
```
|
||||
|
||||
### ValidationRule-Interface
|
||||
|
||||
Das Basis-Interface für alle Validierungsregeln:
|
||||
|
||||
```php
|
||||
interface ValidationRule
|
||||
{
|
||||
public function validate(mixed $value): bool;
|
||||
public function getErrorMessages(): array;
|
||||
}
|
||||
```
|
||||
|
||||
Alle Validierungsregeln implementieren dieses Interface und werden als PHP-Attribute verwendet.
|
||||
|
||||
### ValidationResult-Klasse
|
||||
|
||||
Speichert und verwaltet Validierungsergebnisse:
|
||||
|
||||
- Sammelt Fehlermeldungen für verschiedene Felder
|
||||
- Bietet Methoden zum Abfragen von Fehlern
|
||||
- Ermöglicht das Zusammenführen mehrerer Validierungsergebnisse
|
||||
|
||||
```php
|
||||
// Fehler prüfen
|
||||
if ($result->hasErrors()) {
|
||||
// Alle Fehlermeldungen abrufen
|
||||
$allErrors = $result->getAllErrorMessages();
|
||||
|
||||
// Fehler für ein bestimmtes Feld abrufen
|
||||
$fieldErrors = $result->getFieldErrors('email');
|
||||
}
|
||||
```
|
||||
|
||||
## Validierungsregeln
|
||||
|
||||
Das Framework bietet eine Vielzahl vordefinierter Validierungsregeln:
|
||||
|
||||
### Grundlegende Regeln
|
||||
|
||||
- **Required**: Stellt sicher, dass ein Wert vorhanden ist
|
||||
- **Email**: Validiert E-Mail-Adressen
|
||||
- **Url**: Validiert URLs
|
||||
- **Numeric**: Stellt sicher, dass ein Wert numerisch ist
|
||||
- **StringLength**: Validiert die Länge eines Strings
|
||||
|
||||
### Erweiterte Regeln
|
||||
|
||||
- **Pattern**: Validiert Werte gegen reguläre Ausdrücke
|
||||
- **Range**: Validiert numerische Werte innerhalb eines Bereichs
|
||||
- **In**: Prüft, ob ein Wert in einer Liste gültiger Werte enthalten ist
|
||||
- **DateFormat**: Validiert Datumsformate
|
||||
- **Phone**: Validiert Telefonnummern
|
||||
- **Ulid**: Validiert ULID-Werte
|
||||
- **IsTrue**: Prüft, ob ein Wert true ist
|
||||
|
||||
### Benutzerdefinierte Regeln
|
||||
|
||||
Eigene Validierungsregeln können durch Implementierung des ValidationRule-Interfaces erstellt werden:
|
||||
|
||||
```php
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final readonly class CustomRule implements ValidationRule
|
||||
{
|
||||
public function __construct(
|
||||
private string $param,
|
||||
private ?string $message = null
|
||||
) {
|
||||
}
|
||||
|
||||
public function validate(mixed $value): bool
|
||||
{
|
||||
// Validierungslogik implementieren
|
||||
return true; // oder false
|
||||
}
|
||||
|
||||
public function getErrorMessages(): array
|
||||
{
|
||||
return [$this->message ?? 'Standardfehlermeldung'];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Objekte mit Attributen validieren
|
||||
|
||||
```php
|
||||
class UserData
|
||||
{
|
||||
#[Required]
|
||||
#[StringLength(min: 3, max: 50)]
|
||||
public string $name;
|
||||
|
||||
#[Required]
|
||||
#[Email]
|
||||
public string $email;
|
||||
|
||||
#[StringLength(max: 500)]
|
||||
public ?string $bio = null;
|
||||
|
||||
#[Range(min: 18)]
|
||||
public ?int $age = null;
|
||||
}
|
||||
|
||||
// Validierung durchführen
|
||||
$userData = new UserData();
|
||||
$userData->name = 'Max';
|
||||
$userData->email = 'invalid-email';
|
||||
|
||||
$result = $validator->validate($userData);
|
||||
```
|
||||
|
||||
### Validierungsgruppen
|
||||
|
||||
Das Framework unterstützt Validierungsgruppen, um verschiedene Validierungsszenarien zu ermöglichen:
|
||||
|
||||
```php
|
||||
class UserData
|
||||
{
|
||||
#[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;
|
||||
}
|
||||
|
||||
// Validierung mit Gruppe durchführen
|
||||
$result = $validator->validate($userData, 'registration');
|
||||
```
|
||||
|
||||
### Fehlerbehandlung
|
||||
|
||||
```php
|
||||
if ($result->hasErrors()) {
|
||||
foreach ($result->getAll() as $field => $errors) {
|
||||
echo "Fehler im Feld '$field':\n";
|
||||
foreach ($errors as $error) {
|
||||
echo "- $error\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration
|
||||
|
||||
### Formular-Validierung
|
||||
|
||||
Das Framework bietet eine `ValidationFormHandler`-Klasse für die Validierung von Formulardaten:
|
||||
|
||||
```php
|
||||
// In einem Controller
|
||||
public function handleForm(Request $request, ValidationFormHandler $formHandler): Response
|
||||
{
|
||||
$formData = $request->getFormData();
|
||||
|
||||
$result = $formHandler->validate(UserData::class, $formData);
|
||||
|
||||
if ($result->hasErrors()) {
|
||||
return $this->renderForm('user_form', [
|
||||
'errors' => $result->getAll(),
|
||||
'data' => $formData
|
||||
]);
|
||||
}
|
||||
|
||||
// Erfolgreiche Validierung, Daten verarbeiten
|
||||
$this->userService->createUser($formData);
|
||||
|
||||
return $this->redirect('/success');
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware-Integration
|
||||
|
||||
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' => UserData::class,
|
||||
'PUT' => UserUpdateData::class
|
||||
]
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
## Erweiterbarkeit
|
||||
|
||||
### Eigene Validierungsregeln erstellen
|
||||
|
||||
1. Interface implementieren:
|
||||
|
||||
```php
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final readonly class Password implements ValidationRule
|
||||
{
|
||||
public function __construct(
|
||||
private int $minLength = 8,
|
||||
private bool $requireSpecialChars = true,
|
||||
private ?string $message = null
|
||||
) {
|
||||
}
|
||||
|
||||
public function validate(mixed $value): bool
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return true; // Leere Werte werden von Required-Regel behandelt
|
||||
}
|
||||
|
||||
if (!is_string($value) || strlen($value) < $this->minLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->requireSpecialChars && !preg_match('/[^a-zA-Z0-9]/', $value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getErrorMessages(): array
|
||||
{
|
||||
return [$this->message ?? "Das Passwort muss mindestens {$this->minLength} Zeichen lang sein und Sonderzeichen enthalten."];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Verwendung:
|
||||
|
||||
```php
|
||||
class UserRegistration
|
||||
{
|
||||
#[Required]
|
||||
#[Email]
|
||||
public string $email;
|
||||
|
||||
#[Required]
|
||||
#[Password(minLength: 10)]
|
||||
public string $password;
|
||||
}
|
||||
```
|
||||
|
||||
### Validierungsgruppen implementieren
|
||||
|
||||
Für Regeln, die Validierungsgruppen unterstützen sollen, implementieren Sie das `GroupAware`-Interface:
|
||||
|
||||
```php
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final readonly class Required implements ValidationRule, GroupAware
|
||||
{
|
||||
/**
|
||||
* @param array<string> $groups Validierungsgruppen
|
||||
*/
|
||||
public function __construct(
|
||||
private ?string $message = null,
|
||||
private array $groups = []
|
||||
) {
|
||||
}
|
||||
|
||||
public function validate(mixed $value): bool
|
||||
{
|
||||
return $value !== null && $value !== '';
|
||||
}
|
||||
|
||||
public function getErrorMessages(): array
|
||||
{
|
||||
return [$this->message ?? 'Dieser Wert ist erforderlich.'];
|
||||
}
|
||||
|
||||
public function belongsToGroup(string $group): bool
|
||||
{
|
||||
return empty($this->groups) || in_array($group, $this->groups);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
### Häufige Probleme
|
||||
|
||||
1. **Validierungsregeln werden nicht angewendet**:
|
||||
- Stellen Sie sicher, dass die Attribute korrekt definiert sind
|
||||
- Überprüfen Sie, ob die Eigenschaften für den Validator zugänglich sind (public oder mit Reflection)
|
||||
|
||||
2. **Falsche Fehlermeldungen**:
|
||||
- Überprüfen Sie die Reihenfolge der Validierungsregeln
|
||||
- Stellen Sie sicher, dass die Regeln für den richtigen Datentyp verwendet werden
|
||||
|
||||
3. **Leistungsprobleme**:
|
||||
- Verwenden Sie ValidationCacheDecorator für häufig validierte Objekte
|
||||
- Vermeiden Sie zu komplexe Validierungsregeln
|
||||
|
||||
## Weiterführende Informationen
|
||||
|
||||
- [Verfügbare Validierungsregeln](rules.md)
|
||||
- [Formular-Integration](examples.md)
|
||||
- [API-Validierung](/guides/api-validation.md)
|
||||
451
docs/components/validation/rules.md
Normal file
451
docs/components/validation/rules.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# Validierungsregeln
|
||||
|
||||
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung der Validierungsregeln korrekt dar.
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Validation Framework bietet eine umfangreiche Sammlung vordefinierter Validierungsregeln, die als PHP-Attribute verwendet werden können. Diese Regeln können auf Objekteigenschaften angewendet werden, um Daten zu validieren und sicherzustellen, dass sie den erwarteten Anforderungen entsprechen.
|
||||
|
||||
## Grundlegende Regeln
|
||||
|
||||
### Required
|
||||
|
||||
Die `Required`-Regel stellt sicher, dass ein Wert vorhanden ist und nicht leer ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Required;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[Required]
|
||||
public string $username;
|
||||
|
||||
#[Required(message: "Die E-Mail-Adresse ist erforderlich.")]
|
||||
public string $email;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
- `groups` (optional): Array von Validierungsgruppen, zu denen diese Regel gehört
|
||||
|
||||
**Validierungslogik:**
|
||||
- Gibt `false` zurück, wenn der Wert `null` oder ein leerer String ist
|
||||
- Gibt `true` zurück für alle anderen Werte, einschließlich `0` und `false`
|
||||
|
||||
### Email
|
||||
|
||||
Die `Email`-Regel validiert, dass ein Wert eine gültige E-Mail-Adresse ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Email;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[Email]
|
||||
public string $email;
|
||||
|
||||
#[Email(message: "Bitte geben Sie eine gültige E-Mail-Adresse ein.")]
|
||||
public string $alternativeEmail;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `filter_var()` mit `FILTER_VALIDATE_EMAIL` zur Validierung
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### StringLength
|
||||
|
||||
Die `StringLength`-Regel validiert die Länge eines Strings:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\StringLength;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[StringLength(min: 3, max: 50)]
|
||||
public string $username;
|
||||
|
||||
#[StringLength(min: 8, message: "Das Passwort muss mindestens 8 Zeichen lang sein.")]
|
||||
public string $password;
|
||||
|
||||
#[StringLength(max: 500)]
|
||||
public ?string $bio;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `min` (optional): Minimale Länge des Strings
|
||||
- `max` (optional): Maximale Länge des Strings
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Mindestens einer der Parameter `min` oder `max` muss gesetzt sein
|
||||
- Verwendet `mb_strlen()` für korrekte Behandlung von Multibyte-Zeichen
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### Url
|
||||
|
||||
Die `Url`-Regel validiert, dass ein Wert eine gültige URL ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Url;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[Url]
|
||||
public string $website;
|
||||
|
||||
#[Url(message: "Bitte geben Sie eine gültige URL ein.")]
|
||||
public string $profileUrl;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `filter_var()` mit `FILTER_VALIDATE_URL` zur Validierung
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### Numeric
|
||||
|
||||
Die `Numeric`-Regel validiert, dass ein Wert numerisch ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Numeric;
|
||||
|
||||
class ProductData
|
||||
{
|
||||
#[Numeric]
|
||||
public $price;
|
||||
|
||||
#[Numeric(message: "Die Menge muss eine Zahl sein.")]
|
||||
public $quantity;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `is_numeric()` zur Validierung
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
## Erweiterte Regeln
|
||||
|
||||
### Pattern
|
||||
|
||||
Die `Pattern`-Regel validiert einen Wert gegen einen regulären Ausdruck:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Pattern;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[Pattern(pattern: '/^[a-zA-Z0-9_]+$/', message: "Der Benutzername darf nur Buchstaben, Zahlen und Unterstriche enthalten.")]
|
||||
public string $username;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `pattern`: Regulärer Ausdruck für die Validierung
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `preg_match()` zur Validierung gegen den angegebenen regulären Ausdruck
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### Range
|
||||
|
||||
Die `Range`-Regel validiert, dass ein numerischer Wert innerhalb eines bestimmten Bereichs liegt:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Range;
|
||||
|
||||
class ProductData
|
||||
{
|
||||
#[Range(min: 0)]
|
||||
public float $price;
|
||||
|
||||
#[Range(min: 1, max: 100, message: "Die Menge muss zwischen 1 und 100 liegen.")]
|
||||
public int $quantity;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `min` (optional): Minimaler Wert
|
||||
- `max` (optional): Maximaler Wert
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Mindestens einer der Parameter `min` oder `max` muss gesetzt sein
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### In
|
||||
|
||||
Die `In`-Regel validiert, dass ein Wert in einer Liste gültiger Werte enthalten ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\In;
|
||||
|
||||
class ProductData
|
||||
{
|
||||
#[In(values: ['small', 'medium', 'large'])]
|
||||
public string $size;
|
||||
|
||||
#[In(values: [1, 2, 3, 4, 5], message: "Bitte wählen Sie eine gültige Kategorie.")]
|
||||
public int $category;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `values`: Array gültiger Werte
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `in_array()` zur Validierung
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### DateFormat
|
||||
|
||||
Die `DateFormat`-Regel validiert, dass ein Wert ein gültiges Datum in einem bestimmten Format ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\DateFormat;
|
||||
|
||||
class EventData
|
||||
{
|
||||
#[DateFormat(format: 'Y-m-d')]
|
||||
public string $date;
|
||||
|
||||
#[DateFormat(format: 'Y-m-d H:i:s', message: "Bitte geben Sie ein gültiges Datum und eine gültige Uhrzeit ein.")]
|
||||
public string $datetime;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `format`: Das erwartete Datumsformat (PHP date()-Format)
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Verwendet `DateTime::createFromFormat()` zur Validierung
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### Phone
|
||||
|
||||
Die `Phone`-Regel validiert, dass ein Wert eine gültige Telefonnummer ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Phone;
|
||||
|
||||
class ContactData
|
||||
{
|
||||
#[Phone]
|
||||
public string $phoneNumber;
|
||||
|
||||
#[Phone(message: "Bitte geben Sie eine gültige Telefonnummer ein.")]
|
||||
public string $mobileNumber;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Validiert Telefonnummern mit einem flexiblen Muster, das verschiedene Formate unterstützt
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### Ulid
|
||||
|
||||
Die `Ulid`-Regel validiert, dass ein Wert ein gültiger ULID (Universally Unique Lexicographically Sortable Identifier) ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Ulid;
|
||||
|
||||
class EntityData
|
||||
{
|
||||
#[Ulid]
|
||||
public string $id;
|
||||
|
||||
#[Ulid(message: "Die ID muss ein gültiger ULID sein.")]
|
||||
public string $parentId;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Validiert, dass der Wert ein gültiger ULID ist (26 Zeichen, Base32-Kodierung)
|
||||
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)
|
||||
|
||||
### IsTrue
|
||||
|
||||
Die `IsTrue`-Regel validiert, dass ein Wert `true` ist:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\IsTrue;
|
||||
|
||||
class RegistrationData
|
||||
{
|
||||
#[IsTrue(message: "Sie müssen die Nutzungsbedingungen akzeptieren.")]
|
||||
public bool $termsAccepted;
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Gibt `true` zurück, wenn der Wert `true` ist
|
||||
- Gibt `false` zurück für alle anderen Werte
|
||||
- Leere Werte werden als ungültig betrachtet
|
||||
|
||||
## Benutzerdefinierte Regeln
|
||||
|
||||
### Custom
|
||||
|
||||
Die `Custom`-Regel ermöglicht die Definition einer benutzerdefinierten Validierungslogik mit einer Callback-Funktion:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Custom;
|
||||
|
||||
class UserData
|
||||
{
|
||||
#[Custom(callback: 'validateUsername', message: "Der Benutzername ist ungültig.")]
|
||||
public string $username;
|
||||
|
||||
private function validateUsername($value): bool
|
||||
{
|
||||
// Benutzerdefinierte Validierungslogik
|
||||
return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $value) === 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Parameter:**
|
||||
- `callback`: Name der Callback-Methode oder Closure
|
||||
- `message` (optional): Benutzerdefinierte Fehlermeldung
|
||||
|
||||
**Validierungslogik:**
|
||||
- Ruft die angegebene Callback-Funktion auf und gibt deren Rückgabewert zurück
|
||||
- Leere Werte werden an die Callback-Funktion übergeben
|
||||
|
||||
## Eigene Validierungsregeln erstellen
|
||||
|
||||
Sie können eigene Validierungsregeln erstellen, indem Sie das `ValidationRule`-Interface implementieren:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\ValidationRule;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final readonly class Password implements ValidationRule
|
||||
{
|
||||
public function __construct(
|
||||
private int $minLength = 8,
|
||||
private bool $requireSpecialChars = true,
|
||||
private ?string $message = null
|
||||
) {
|
||||
}
|
||||
|
||||
public function validate(mixed $value): bool
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return true; // Leere Werte werden von Required-Regel behandelt
|
||||
}
|
||||
|
||||
if (!is_string($value) || strlen($value) < $this->minLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->requireSpecialChars && !preg_match('/[^a-zA-Z0-9]/', $value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getErrorMessages(): array
|
||||
{
|
||||
return [$this->message ?? "Das Passwort muss mindestens {$this->minLength} Zeichen lang sein und Sonderzeichen enthalten."];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Validierungsgruppen
|
||||
|
||||
Für Regeln, die Validierungsgruppen unterstützen sollen, implementieren Sie das `GroupAware`-Interface:
|
||||
|
||||
```php
|
||||
use App\Framework\Validation\ValidationRule;
|
||||
use App\Framework\Validation\GroupAware;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final readonly class Required implements ValidationRule, GroupAware
|
||||
{
|
||||
/**
|
||||
* @param array<string> $groups Validierungsgruppen
|
||||
*/
|
||||
public function __construct(
|
||||
private ?string $message = null,
|
||||
private array $groups = []
|
||||
) {
|
||||
}
|
||||
|
||||
public function validate(mixed $value): bool
|
||||
{
|
||||
return $value !== null && $value !== '';
|
||||
}
|
||||
|
||||
public function getErrorMessages(): array
|
||||
{
|
||||
return [$this->message ?? 'Dieser Wert ist erforderlich.'];
|
||||
}
|
||||
|
||||
public function belongsToGroup(string $group): bool
|
||||
{
|
||||
return empty($this->groups) || in_array($group, $this->groups);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Kombinieren von Regeln
|
||||
|
||||
Validierungsregeln können kombiniert werden, um komplexe Validierungsanforderungen zu erfüllen:
|
||||
|
||||
```php
|
||||
class UserData
|
||||
{
|
||||
#[Required]
|
||||
#[StringLength(min: 3, max: 50)]
|
||||
#[Pattern(pattern: '/^[a-zA-Z0-9_]+$/')]
|
||||
public string $username;
|
||||
|
||||
#[Required]
|
||||
#[Email]
|
||||
public string $email;
|
||||
|
||||
#[Required]
|
||||
#[StringLength(min: 8)]
|
||||
#[Custom(callback: 'validatePassword')]
|
||||
public string $password;
|
||||
|
||||
private function validatePassword($value): bool
|
||||
{
|
||||
// Mindestens ein Großbuchstabe, ein Kleinbuchstabe, eine Zahl und ein Sonderzeichen
|
||||
return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).+$/', $value) === 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Weiterführende Informationen
|
||||
|
||||
- [Validation Framework Übersicht](index.md)
|
||||
- [Beispiele für die Verwendung von Validierungsregeln](examples.md)
|
||||
- [API-Validierung](/guides/api-validation.md)
|
||||
Reference in New Issue
Block a user