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

11 KiB

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

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

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

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

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:

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:

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:

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

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

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

Konfiguration in config/validation.php:

return [
    'routes' => [
        '/api/users' => [
            'POST' => UserCreateData::class,
            'PUT' => UserUpdateData::class
        ],
        '/api/products' => [
            'POST' => ProductCreateData::class,
            'PUT' => ProductUpdateData::class
        ]
    ]
];

API-Controller mit Validierung

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:

{
    "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:

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:

// 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
// Korrekte Initialisierung des Validators
$validator = new Validator($reflectionProvider);

Falsche Fehlermeldungen

Überprüfen Sie die Reihenfolge der Validierungsregeln:

// Korrekte Reihenfolge: Required vor anderen Regeln
#[Required]
#[Email]
public string $email;

Leistungsprobleme

Verwenden Sie den ValidationCacheDecorator und vermeiden Sie zu komplexe Validierungsregeln:

// Einfache Regeln verwenden
#[StringLength(max: 255)] // Besser als komplexe reguläre Ausdrücke
public string $name;

Weiterführende Informationen