W3docs

PHP Formularvalidierung

Formularvalidierung ist ein wesentlicher Bestandteil der Webentwicklung und stellt sicher, dass eingegebene Daten korrekt und vollständig sind, bevor sie verarbeitet werden.

Formularvalidierung ist der Prozess, bei dem überprüft wird, ob die Daten, die ein Benutzer über ein HTML-Formular einsendet, vorhanden, korrekt formatiert und sicher zu verwenden sind — und zwar bevor Ihr Skript darauf reagiert. In PHP läuft die Validierung auf dem Server, nachdem das Formular abgesendet wurde, sodass sie nicht durch das Deaktivieren von JavaScript oder das direkte Senden einer Anfrage umgangen werden kann.

Dieses Kapitel behandelt den vollständigen Validierungsablauf: warum serverseitige Validierung wichtig ist, den Unterschied zwischen Bereinigen und Validieren, die PHP-Funktionen, die Sie dafür benötigen, sowie ein vollständiges, sicheres Beispiel, das Sie anpassen können. Wenn Sie neu im Empfangen von Formulareingaben sind, lesen Sie zunächst PHP Formularverarbeitung.

Warum serverseitige Validierung wichtig ist

Clientseitige Validierung (HTML5 required, type="email", JavaScript) verbessert die Benutzererfahrung, indem Fehler sofort abgefangen werden — sie ist jedoch nur eine Komfortfunktion. Ein entschlossener oder böswilliger Benutzer kann JavaScript deaktivieren oder eine manipulierte HTTP-Anfrage senden, die den Browser vollständig umgeht. Der Server ist der einzige Ort, an dem Validierung vertrauenswürdig ist. Die serverseitige PHP-Validierung ermöglicht es Ihnen:

  • Zu garantieren, dass erforderliche Felder tatsächlich vorhanden und nicht leer sind.
  • Zu bestätigen, dass Werte dem erwarteten Format entsprechen (eine echte E-Mail-Adresse, eine Zahl im gültigen Bereich).
  • Gefährliche Eingaben zu neutralisieren, bevor sie eine Datenbank oder eine HTML-Seite erreichen, und so SQL-Injection und Cross-Site-Scripting (XSS) zu verhindern.

Behandeln Sie jeden Wert in $_POST, $_GET und $_REQUEST als nicht vertrauenswürdig, bis Sie ihn überprüft haben. Diese Arrays stammen aus PHPs Superglobals.

Bereinigen vs. Validieren

Diese beiden Begriffe werden oft verwechselt, aber sie erfüllen unterschiedliche Aufgaben:

  • Bereinigen säubert einen Wert — es werden unerwünschte Zeichen entfernt oder maskiert. trim() entfernt umgebende Leerzeichen; htmlspecialchars() wandelt <, >, & und Anführungszeichen in HTML-Entitäten um, sodass sie als Text dargestellt werden, anstatt ausgeführt zu werden.
  • Validieren prüft einen Wert anhand einer Regel und gibt an, ob er bestanden hat oder nicht — der Wert wird dabei nicht verändert. filter_var($email, FILTER_VALIDATE_EMAIL) gibt die E-Mail-Adresse zurück, wenn sie gültig aussieht, oder false, wenn nicht.

Ein typischer Ablauf ist: zuerst bereinigen (Leerzeichen entfernen), dann validieren und schließlich bei der Ausgabe maskieren (wenn der Wert wieder in HTML ausgegeben wird). Für eine tiefere Behandlung des PHP-Filtersystems siehe PHP Filter und filter_var().

Validierungsschritte

Eine serverseitige Validierungsroutine folgt in der Regel denselben vier Schritten:

  1. Das HTML-Formular erstellen und seine action auf das PHP-Skript zeigen lassen.
  2. Eine POST-Übermittlung mit $_SERVER["REQUEST_METHOD"] erkennen.
  3. Für jedes Feld: den Wert lesen, bereinigen, dann validieren — und dabei Fehlermeldungen sammeln.
  4. Wenn jedes Feld die Prüfung bestanden hat, die Daten verarbeiten; andernfalls das Formular mit den Fehlermeldungen und den bereits eingegebenen Werten erneut anzeigen.

Nützliche PHP-Validierungsfunktionen

FunktionZweck
trim()Entfernt Leerzeichen am Anfang und Ende eines Strings.
empty()Prüft, ob ein Wert fehlt oder ein leerer String ist.
filter_var()Validiert oder bereinigt mit einem eingebauten Filter (z. B. FILTER_VALIDATE_EMAIL, FILTER_VALIDATE_INT).
is_numeric()Gibt true zurück, wenn der Wert eine Zahl oder ein numerischer String ist.
htmlspecialchars()Maskiert HTML-Sonderzeichen, um XSS bei der Ausgabe zu verhindern.
preg_match()Validiert anhand eines benutzerdefinierten regulären Ausdrucksmusters.

Ein minimales Beispiel

Vor dem vollständigen Datenbankbeispiel unten folgt hier das kleinste Validierungsbeispiel, das das Kernmuster zeigt — bereinigen, dann validieren, dann Fehler sammeln:

<?php
$email = trim($_POST["email"] ?? "");
$errors = [];

if ($email === "") {
    $errors["email"] = "Please enter your email.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors["email"] = "Please enter a valid email address.";
}

if (empty($errors)) {
    echo "Valid email: " . htmlspecialchars($email);
} else {
    echo $errors["email"];
}
?>

Wenn $_POST["email"] den Wert " [email protected] " hat, werden die umgebenden Leerzeichen entfernt, der Wert wird validiert, und das Skript gibt Valid email: [email protected] aus. Eine Eingabe wie "not-an-email" erzeugt Please enter a valid email address.

Vollständiges Beispiel: Ein Formular validieren und speichern

Das folgende Beispiel validiert einen Namen, eine E-Mail-Adresse, ein Geschlecht und einen Kommentar und fügt dann die Zeile mit einem Prepared Statement ein — der Prepared-Statement-Ansatz (mit mysqli) schützt vor SQL-Injection, da Benutzereingaben getrennt vom SQL-Text gesendet werden und niemals als Code interpretiert werden.

Aktualisieren Sie die Datenbankzugangsdaten und stellen Sie sicher, dass Ihre Datenbank eine users-Tabelle mit den Spalten name, email, gender und comment enthält, bevor Sie dieses Beispiel ausführen.

<?php
// Database connection setup
$link = mysqli_connect("localhost", "username", "password", "database");
if (!$link) {
    die("Connection failed: " . mysqli_connect_error());
}

// Define variables and initialize with empty values
$name = $email = $gender = $comment = $website = "";
$name_err = $email_err = $gender_err = $comment_err = "";
 
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // Validate name
    if(empty(trim($_POST["name"] ?? ""))){
        $name_err = "Please enter your name.";
    } else{
        $name = trim($_POST["name"]);
    }
    
    // Validate email
    if(empty(trim($_POST["email"] ?? ""))){
        $email_err = "Please enter your email.";
    } elseif(!filter_var(trim($_POST["email"] ?? ""), FILTER_VALIDATE_EMAIL)) {
        $email_err = "Please enter a valid email address.";
    } else{
        $email = trim($_POST["email"]);
    }
    
    // Validate gender
    if(!isset($_POST["gender"]) || empty($_POST["gender"])){
        $gender_err = "Please select your gender.";
    } else{
        $gender = $_POST["gender"];
    }
    
    // Validate comment
    if(empty(trim($_POST["comment"] ?? ""))){
        $comment_err = "Please enter your comment.";
    } else{
        $comment = trim($_POST["comment"]);
    }
    
    // Check input errors before inserting in database
    if(empty($name_err) && empty($email_err) && empty($gender_err) && empty($comment_err)){
        // Prepare an insert statement
        $sql = "INSERT INTO users (name, email, gender, comment) VALUES (?, ?, ?, ?)";
         
        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "ssss", $param_name, $param_email, $param_gender, $param_comment);
            
            // Set parameters
            $param_name = $name;
            $param_email = $email;
            $param_gender = $gender;
            $param_comment = $comment;
            
            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                // Records created successfully. Redirect to landing page
                header("location: index.php");
                exit();
            } else{
                echo "Something went wrong. Please try again later.";
            }
        }
         
        // Close statement
        mysqli_stmt_close($stmt);
    }
}

// Close connection
mysqli_close($link);
?>
<!DOCTYPE html>
<html>
<head><title>PHP Form Validation</title></head>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
    Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
    <span class="error"><?php echo $name_err; ?></span><br><br>
    Email: <input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>">
    <span class="error"><?php echo $email_err; ?></span><br><br>
    Gender:
    <input type="radio" name="gender" value="female"> Female
    <input type="radio" name="gender" value="male"> Male
    <span class="error"><?php echo $gender_err; ?></span><br><br>
    Comment: <textarea name="comment"><?php echo htmlspecialchars($comment); ?></textarea>
    <span class="error"><?php echo $comment_err; ?></span><br><br>
    <input type="submit" value="Submit">
</form>
</body>
</html>

Fehler anzeigen und Benutzereingaben behalten

Beachten Sie drei Details im Beispiel, die für eine gute Formular-UX sorgen:

  • Jede Fehlervariable ($name_err, $email_err, …) wird in einem <span class="error"> neben dem entsprechenden Feld ausgegeben, sodass der Benutzer genau weiß, welche Eingabe er korrigieren muss.
  • Die action des Formulars gibt htmlspecialchars($_SERVER["PHP_SELF"]) aus. Ohne Maskierung kann PHP_SELF ausgenutzt werden, um Skripte über die URL einzuschleusen — das Maskieren ist daher eine Sicherheitsmaßnahme und nicht nur eine Formatierungsfrage.
  • Jeder Wert, der erneut im Formular angezeigt wird, wird durch htmlspecialchars() geleitet. Dies verhindert XSS und ermöglicht es dem Benutzer, seine bereits eingegebenen Daten zu behalten, anstatt nach einem ungültigen Feld alles erneut eingeben zu müssen.

Häufige Fallstricke

  • empty() behandelt "0" als leer. Ein Feld, dessen Wert der String "0" ist, schlägt bei einer empty()-Prüfung fehl. Für Felder, bei denen 0 ein gültiger Wert ist, vergleichen Sie explizit: if ($value === "").
  • Vor der Typannahme validieren. $_POST-Werte sind immer Strings. Verwenden Sie filter_var($n, FILTER_VALIDATE_INT) oder is_numeric(), anstatt davon auszugehen, dass eine Zahl eingegangen ist.
  • Bei der Ausgabe maskieren, nicht bei der Speicherung. Speichern Sie den rohen (validierten) Wert in der Datenbank und verwenden Sie htmlspecialchars() nur beim Ausgeben in HTML. Das Maskieren vor der Speicherung beschädigt die Daten für Nicht-HTML-Verwendungen.
  • Den Null-Koaleszenz-Operator verwenden. $_POST["x"] ?? "" vermeidet Warnungen wie "Undefined array key", wenn ein Feld fehlt.

Andere Feldtypen validieren

Dasselbe Muster lässt sich auf jedes Feld anwenden — nur die Validierungsregel ändert sich:

<?php
// Age: an integer between 18 and 120
$age = filter_var($_POST["age"] ?? "", FILTER_VALIDATE_INT, [
    "options" => ["min_range" => 18, "max_range" => 120],
]);
if ($age === false) {
    echo "Please enter an age between 18 and 120.";
}

// Username: 3-16 letters, digits, or underscores
$username = trim($_POST["username"] ?? "");
if (!preg_match('/^[A-Za-z0-9_]{3,16}$/', $username)) {
    echo "Username must be 3-16 letters, digits, or underscores.";
}
?>

Für URL- und E-Mail-spezifische Regeln siehe PHP-Formular URL & E-Mail; für das Markieren von Pflichtfeldern siehe PHP-Formular Pflichtfelder; und um alle Teile zusammengesetzt zu sehen, siehe PHP Vollständiges Formular.

Fazit

Serverseitige Validierung in PHP macht ein Formular vertrauenswürdig: Sie bestätigt, dass Daten vorhanden und korrekt formatiert sind, und — in Kombination mit htmlspecialchars() bei der Ausgabe und Prepared Statements bei der Speicherung — verhindert sie XSS und SQL-Injection. Das Grundrezept ist immer dasselbe: bereinigen, validieren, Fehler sammeln und das Formular mit hilfreichen Meldungen erneut anzeigen, wenn etwas nicht stimmt. Beherrschen Sie diese Schleife, und Sie können jedes Feld validieren, indem Sie einfach eine andere Regel einsetzen.

Übung

Übung
Was sind einige wichtige Elemente der PHP-Formularvalidierung?
Was sind einige wichtige Elemente der PHP-Formularvalidierung?
Was this page helpful?