Files
michaelschiemer/docs/components/validation/index.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

8.1 KiB

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:

// 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:

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
// 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:

#[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

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:

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

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:

// 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:

// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(InputValidationMiddleware::class);

Konfiguration in config/validation.php:

return [
    'routes' => [
        '/api/users' => [
            'POST' => UserData::class,
            'PUT' => UserUpdateData::class
        ]
    ]
];

Erweiterbarkeit

Eigene Validierungsregeln erstellen

  1. Interface implementieren:
#[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."];
    }
}
  1. Verwendung:
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:

#[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