Formchecker mit PHP

QUEST08

Erfahrenes Mitglied
Hallo,

bisher habe ich meine Formulare relativ gut auf Richtigkeit geprüft, jedoch z.B. nur ausgegeben, dass das Feld z.B. "Name" nur Buchstaben enthalten darf, ODER das "Name" mind. 3 Zeichen lang sein soll. Ich habe als max. eine Meldung ausgegeben.

Nun möchte ich jedoch folgendes realisieren:
- Eine globale Datei, wo alle Felder, dessen Bedinngungen und dessen Fehlermeldung festgelegt sind

Ziel:
Ich möchte nach dem Senden des Formulares eine genaue Fehlerausgabe realisieren. Z.B.: Name darf keine Sonderzeichen enthalten, Name muss mind. 3 Zeichen lang sein, Name darf maximal 15 Zeichen lang sein, Name darf keine Zahlen enthalten.


Ich habe gestern Mootools Floor entdeckt, welches mir super gefallen würde, jedoch bin ich prinzipiell gegen solche Javascript-Sachen, da meine Seite für alle vom Funktionsumfang her gleich sein sollte. Zudem müsste ich jedes Feld nach dem absenden dennoch prüfen.

Hat da jemand einen einfachen Vorschlag? Ich denke das könnte man irgendwie mit Array's lösen, jedoch fehlt mir absoulut der Ansatz.
 
Ich würde pro prüfendes Feld eine Checker-Funktion schreiben.
PHP:
<?php

//Beispielaufruf

//$_POST simulieren
$_POST = array('name' => 'y1');

$valid = checkName($_POST['name'], $messages);
if($valid){
    echo "Feld Namen mit dem Inhalt '{$_POST['name']}' ist gültig";
}else{
    echo "Feld Namen mit dem Inhalt '{$_POST['name']}' ist ungültig:<br />";
    echo implode('<br />', $messages);
}

// === CHECKER-FUNKTIONEN ===

/**
 * Feld: Name 
 * @param String        in      Zu prüfenden Wert
 * @param Array<String> out     Rückgabe der Fehlermeldungen
 * @return Boolean              Valid
 */
function checkName($value, &$messages){
    $messages = array();
    $valid = true;
    if(strlen($value) < 3){
        $valid = false;
        $messages[] = 'Name muss mindestens 3 Zeichen lang sein';
    }        
    if(strlen($value) > 15){
        $valid = false;
        $messages[] = 'Name darf höchstens 15 Zeichen lang sein';
    }        
    if(preg_match('/^[[:alpha:]_]*$/', $value)==0){
        $valid = false;
        $messages[] = 'Name darf nur aus Buchstaben und _ bestehen';            
    }  
    return $valid;      
}
?>

Ausgabe:
Code:
Feld Namen mit dem Inhalt 'y1' ist ungültig:
Name muss mindestens 3 Zeichen lang sein
Name darf nur aus Buchstaben und _ bestehen
 
Du könntest dir auch eine Tabelle anlegen wo du den entsprechenden Feldnamen (des Formulars), die minimale Länge, die maximale Länge und die erlaubten Zeichen (in der oder ähnlicher Form "/^[[:alpha:]_]*$/") speicherst.

Code:
feld - min - max - zeichen           - fehlertext
name -   3 -  15 - /^[[:alpha:]_]*$/ - Die Angaben sind ungültig
plz  -   5 -   5 - [0-9]             - Postleitzahl ungültig

Dann nimmst du die Funktion von yaslaw und liest dort die Angaben aus der DB aus und vergleichst damit.
 
Hallo ihr beiden,

das mit der DB hab ich mir auch bereits überlegt, jedoch müsste ich dann jedes mal die Abfrage starten. Dennoch würde ich so eine Übersicht (ganz oben vor den Funktionen) begrüßen. Das kann man doch sicherlich auch als Array lösen, oder?

Ansonsten funktioniert der Code von yaslaw wunderbar. Werde das ganze jetzt ersteinmal genau testen und zurechtschreiben.

Habt ihr noch eine Idee, wie ich diese Übersicht ohne DB lösen kann?
 
So wie du es schon selber geschrieben hast, mit einem (mehrdimensionalen) Array.

Dann erweiterst du eventuell die Funktion noch um den Parameter "Feldnummer" und kannst dann den Index des Arrays beim Aufruf mitliefern.
 
Hab das ganze jetzt wie folgt gelöst:

PHP:
<?php

$FELD = array();

$FELD['vorname']  = array('minlength' => "3",'maxlength' => "15", 'characters' => "/^[a-zA-Z]+$/s");
$FELD['nachname'] = array('minlength' => "3",'maxlength' => "15", 'characters' => "/^[a-zA-Z]+$/s");

$valid = checkVorname($_POST['vorname'], $messages);
if($valid){
    echo "Feld Namen mit dem Inhalt '{$_POST['vorname']}' ist gültig";
}else{
    echo "Feld Namen mit dem Inhalt '{$_POST['vorname']}' ist ungültig:<br />";
    echo implode('<br />', $messages);
}

$valid = checkNachname($_POST['nachname'], $messages);
if($valid){
    echo "Feld Namen mit dem Inhalt '{$_POST['nachname']}' ist gültig";
}else{
    echo "Feld Namen mit dem Inhalt '{$_POST['nachname']}' ist ungültig:<br />";
    echo implode('<br />', $messages);
}

//==== Check-Funktion für "Vorname"
function checkVorname($value, &$messages){
    $messages = array();
    $valid = true;
    if(strlen($value) < $FELD['vorname']['minlength']){
        $valid = false;
        $messages[] = 'Vorname muss mindestens 3 Zeichen lang sein';
    }        
    if(strlen($value) > $FELD['vorname']['maxlength']){
        $valid = false;
        $messages[] = 'Vorname darf höchstens 15 Zeichen lang sein';
    }        
    if(preg_match($FELD['vorname']['characters'], $value)==0){
        $valid = false;
        $messages[] = 'vorname darf nur aus Buchstaben und _ bestehen';            
    }  
    return $valid;      
}

//==== Check-Funktion für "Nachname"
function checkNachname($value, &$messages){
    $messages = array();
    $valid = true;
    if(strlen($value) < $FELD['nachname']['minlength']){
        $valid = false;
        $messages[] = 'Nachname muss mindestens 3 Zeichen lang sein';
    }        
    if(strlen($value) > $FELD['nachname']['maxlength']){
        $valid = false;
        $messages[] = 'Nachname darf höchstens 15 Zeichen lang sein';
    }        
    if(preg_match($FELD['nachname']['characters'], $value)==0){
        $valid = false;
        $messages[] = 'Nachname darf nur aus Buchstaben und _ bestehen';            
    }  
    return $valid;      
}

?>

Jedoch bekomme ich den Fehler, dass regexp leer sein soll. Hab es mit " sowie mit ' sowie ohne versucht anzugeben.
 
Wiederholdender Code sollte man in Funktionen zusammenfassen

PHP:
$valid = true;
$valid = check('vorname', 'checkVorname') ? $valid : false;
$valid = check('nachname', 'checkNachname') ? $valid : false;

//$valid hat ist nur true wenn alle Prüfungen erfolgreich waren.

/**
 * führt einen Check aus und gibt die Fehlermeldung aus
 * @param String        in      Name des zu prüfenden Wertes
 * @param String        in      Name der Check-Funktiom
 * @return Boolean              Valid
 */
function check($fieldName, $checkFunctionName){
    $valid = $checkFunctionName($_POST[$fieldName], $messages);
    if($valid){
        echo "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist gültig";
    }else{
        echo "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist ungültig:<br />";
        echo implode('<br />', $messages);
    }
    return $valid; 
}
//Hier kommen die Check-Funktionen

Nachtrag:
$FELD ist innerhalb der Funktionen nicht bekannt.
mit $GLOBALS['FELD'] oder über die Funktion globals kannst du drauf zugreifen
Kuckst du: http://wiki.yaslaw.info/wikka/PhpVarInFunction
 
Zuletzt bearbeitet:
So, habe das ganze jetzt mal zum laufen gebracht. Jedoch bleiben noch Fragen offen. Hier erstmal der aktuelle Stand:

PHP:
<?php

$GLOBALS['FELD'] = array();
$GLOBALS['FELD']['vorname']  = array('minlength' => "3", 'maxlength' => "15", 'characters' => "\/^[a-zA-Z]+$/s");
$GLOBALS['FELD']['nachname'] = array('minlength' => "3", 'maxlength' => "15", 'characters' => "\/^[a-zA-Z]+$/s");

$valid = true;
$valid = check('vorname', 'checkVorname') ? $valid : false;
$valid = check('nachname', 'checkNachname') ? $valid : false;

function check($fieldName, $checkFunctionName){
    $valid = $checkFunctionName($_POST[$fieldName], $messages);
    if($valid){
        echo "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist gültig";
    }else{
        echo "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist ungültig:<br />";
        echo implode('<br />', $messages);
    }
    return $valid; 
}


//==== Check-Funktion für "Vorname"
function checkVorname($value, &$messages){
    $messages = array();
    $valid = true;
    if(strlen($value) < $GLOBALS['FELD']['vorname']['minlength']){
        $valid = false;
        $messages[] = 'vorname muss mindestens '.$GLOBALS['FELD']['vorname']['minlength'].' Zeichen lang sein';
    }        
    if(strlen($value) > $GLOBALS['FELD']['vorname']['maxlength']){
        $valid = false;
        $messages[] = 'vorname darf höchstens 15 Zeichen lang sein';
    }        
    if(preg_match('/^[a-zA-Z]+$/s', $value)==0){
        $valid = false;
        $messages[] = 'vorname darf nur aus Buchstaben und _ bestehen';            
    }  
    return $valid;      
}

//==== Check-Funktion für "Vorname"
function checkNachname($value, &$messages){
    $messages = array();
    $valid = true;
    if(strlen($value) < $GLOBALS['FELD']['nachname']['minlength']){
        $valid = false;
        $messages[] = 'nachname muss mindestens '.$GLOBALS['FELD']['nachname']['minlength'].' Zeichen lang sein';
    }        
    if(strlen($value) > $GLOBALS['FELD']['nachname']['maxlength']){
        $valid = false;
        $messages[] = 'nachname darf höchstens 15 Zeichen lang sein';
    }        
    if(preg_match('/^[a-zA-Z]+$/s', $value)==0){
        $valid = false;
        $messages[] = 'nachname darf nur aus Buchstaben und _ bestehen';            
    }  
    return $valid;      
}

?>

HTML:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=uft-8">
<meta http-equiv="Content-Language" content="de">
</head>

<body>
  <form method="POST" action="test-check.php">
    <input type="text" name="vorname" size="37" tabindex="2">
  </form>
  <form method="POST" action="test-check.php">
    <input type="text" name="nachname" size="37" tabindex="2">
  </form>
</body>

</html>

Das ganze sieht ja schon recht schick aus. Nur wenn ich um die 10 oder 15 Felder hab wirds schon sehr lang. Gibt es die Möglichkeit, die Funktion per Schleife erstellen zu lassen? Das heißt, zusätzlich zu z.B. $GLOBALS['FELD']['vorname']['minlength'] eine passende Fehlermeldung ins Array packen und das ganze als Schleife aufrufen. Ich kann gerne vorab die Felder neben dem globalen Array vorgeben.

Wenn ich richtig liege, müsste ich die Felder in ein extra Array schreiben und dann per foreach die Schleife durchlaufen lassen. Richtig? Und wenn ja, wie bekomme ich passend die variablen Fehlermeldungen hin?

EDIT: Zusätzlich wäre es natürlich schick, wenn ich die Fehlermeldungen direkt beim jeweiligen Feld erst ausgeben lassen könnte. Aber das würde ich dann schon hinbekommen.
 
Zuletzt bearbeitet:
Ist folgender Abschnitt korrekt?

PHP:
//Zu prüfende Felder des aktuellen Formulars
$checkfields = array("vorname", "nachname");

//Anzahl der Felder auslesen
$anzahlcheckfields = count($checkfields);

//$valid ist nur true, wenn alle Felder korrekt ausgefüllt wurden
$valid = true;

$count = 0;
while($count < $anzahlcheckfields)
{
  $checkanweisung = "check$checkfields[$count]";
  $$valid = check($checkfields[$count], $checkanweisung) ? $valid : false;
$count++;
}

//Schleife ergibt:
/*$valid = check('vorname', 'checkVorname') ? $valid : false;
$valid = check('nachname', 'checkNachname') ? $valid : false;*/

Wenn ja, hat sich der Post darüber noch nicht erledigt :-)
 
Zuletzt bearbeitet:
Warum $$value? Da ist ein $ zuviel.

Den counter kannst du dir sparen, geh mit einer foreach-Schleife durch

Ich hab hier mal was angepasst. AM Schluss hast du einen Array $htmlMessages, der in der gleichen Reihenfolge wie $checkfields die Meldungen enthält
PHP:
//Zu prüfende Felder des aktuellen Formulars
$checkfields = array("vorname", "nachname");

//$valid ist nur true, wenn alle Felder korrekt ausgefüllt wurden
$valid = true;

foreach($checkfields as $index => $field){
  $checkanweisung = "check$checkfields[$count]";
  $valid = check($field, $checkanweisung, $htmlMessage) ? $valid : false;
  $htmlMessages[$index] = $htmlMessage;
} 

//$valid hat ist nur true wenn alle Prüfungen erfolgreich waren.

/**
 * führt einen Check aus und gibt die Fehlermeldung aus
 * @param String        in      Name des zu prüfenden Wertes
 * @param String        in      Name der Check-Funktiom
 * @param String        out     Rückgabe der Fehlermeldung
 * @return Boolean              Valid
 */
function check($fieldName, $checkFunctionName, &$htmlMessage){
    $valid = $checkFunctionName($_POST[$fieldName], $messages);
    $htmlMessages = array();
    if($valid){
        $htmlMessages =  "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist gültig";
    }else{
        $htmlMessages = "Feld {$fieldName} mit dem Inhalt '{$_POST[$fieldName]}' ist ungültig:<br />";
        $htmlMessages .= implode('<br />', $messages);
    }
    return $valid; 
}[
 
Zurück