Um meiner Übersicht über das Zend Framework etwas Leben einzuhauchen, habe ich beschlossen ein kleines Tutorial über die Validierung von Eingaben zu schreiben. Es ist zum Überfliegen oder auch Nachbauen gedacht und soll einen kleinen Einblick in die Arbeitsweise des Zend Frameworks geben. Ein komplettes Skript mit den hier erklärten Inhalten ist hier zu finden.

Das Zend Framework stellt für die Validierung und die Verarbeitung verschiedene Objekte zur Verfügung. Für die Validierung ist das Modul Zend_Validate zuständig. Für die Nachverarbeitung Zend_Filter. Um Filter und Validatoren gesammelt auf eine Eingabe auszuführen, wird ein spezielles Objekt vom Typ Zend_Filter_Input verwendet.

Zend_Validate

Dieses Paket enthält mehrere Klassen, mit deren Hilfe Werte geprüft werden können. Jede Klasse bietet dabei die Methode isValid($value) an. Je nachdem was geprüft werden soll, muss die entsprechende Klasse instanziiert und schließlich die Methode isValid aufgerufen werden. Folgendes Beispiel zeigt wie geprüft werden kann ob ein gegebener Wert eine Ganzzahl ist:

$value = 1234;
$value2 = "otto";
$validator = new Zend_Validate_Int();
$validator->isValid($value); //true
$validator->isValid($value2); //false

Ein Array mit den exakten Fehlermeldungen erhält man mit $validator->getMessages(). Jede Klasse hat dabei eigene Fehlermeldungen, die in der Dokumentation zu finden sind. Dabei gibt es eine ganze Reihe von Validierungsobjekten für jeden erdenklichen Fall:

  • Zend_Validate_Alnum = Prüft ob Wert ausschließlich alphanumerische Zeichen enthält (Achtung: Umlaute sind keine alphanumerischen Zeichen)
  • Zend_Validate_Email = Prüft ob der Wert eine Emailadresse darstellt (optional sogar mit Prüfung ob für die angegebene Domain ein MX Eintrag existiert)
  • Zend_Validate_Between = Prüft ob Wert zwischen zwei Werten liegt.
  • weitere siehe Dokumentation

Neben den oben genannten Validate Klassen kann auch selbst eine Validierungsklasse erstellt werden. Das Beispielskript enthält so eine Beispielklasse.

Zend_Filter

Um den Inhalt von Variablen zu verarbeiten, gibt es die Zend_Filter Klassen. Hier wird ebenfalls eine gewünschte Klasse instanziiert und dann der zu verändernde Wert an die Methode filter($value) übergeben. Folgender Filter entfernt alle nicht alphanumerischen Zeichen aus einem String:

$value = "Das ist <blbl> test öäü. (bla)";
$filter = new Zend_Filter_Alnum(true); // true = auch Leerzeichen sind erlaubt
$filteredValue = $filter->filter($value);
echo $filteredValue; // liefert: Das ist blbl test  bla

Auch hier ist die Liste lang, so gibt es Filter die alle HTML Tags aus einem String entfernen, Sonderzeichen in HTML Entitäten umwandeln, Leerzeichen entfernt etc. (siehe Dokumentation):

Zend_Filter_Input

Für sich sind Validatoren und Filter zwar komfortabel, der wirkliche Vorteil kommt aber erst durch den Einsatz der Klasse Zend_Filter_Input zum Vorschein. Dies ist kein gewöhnlicher Filter, sondern eine Klasse, die es ermöglicht Filter und Validatoren in einem Durchlauf auf einen Satz an Eingaben (z.B. Formulardaten) anzuwenden. Ein Beispiel zeigt am besten wie elegant und übersichtlich so die Eingabeverarbeitung wird.

Als Beispiel wird ein einfaches Eingabeformular, wie es bei einem herkömmlichen Blog verwendet wird validiert.

input formular

Der HTML Quellcode hinter diesem Formular, wie man ihn kennt, ohne Besonderheiten:

<form action="index.php" method="post">
<label>Name:</label> <input type="text" name="name" />
<label>Email:</label> <input type="text" name="email" />
<label>Homepage:</label> <input type="text" name="homepage" />
<label>Nachricht:</label> <textarea name="message"></textarea>
<input type="submit" value="abschicken" name="submit" />
</form>

Nun sollen für alle Eingabefelder überflüssige führende und folgende Leerzeichen entfernt werden (z.B. “  Heinz Müller ” zu “Heinz Müller”). Der Name darf nur aus alphanumerischen Zeichen bestehen, sonst soll eine Fehlermeldung erscheinen. Die Email Adresse soll gültig sein, also @ und eine gültige Domain enthalten. Das Feld Homepage ist optional und im Feld Nachricht sind keine HTML Tags erlaubt und sollen, falls vorhanden, entfernt werden.

In dem verarbeitenden PHP Skript index.php werden zuerst die nötigen Zend Klassen inkludiert:

require_once('Zend/Filter/Input.php');
require_once('Zend/Filter/StringTrim.php');
require_once('Zend/Filter/StripTags.php');
require_once('Zend/Validate/EmailAddress.php');
require_once('Zend/Validate/Alnum.php');

Dann werden die nötigen Zend Validatoren vorbereitet. Dabei werden die per default eingestellten Nachrichten, die im Fehlerfalle ausgegeben werden, mit deutschen Texten überschrieben. Dies geschieht mit der Funktion setMessage($message, $error) die als ersten Parameter die neue Fehlermeldung und als zweiten Parameter die Fehlerart erwartet. Letzterer findet sich in der API Beschreibung der jeweiligen Klasse und unterscheidet sich auch je nach verwendeter Validierungs-Klasse

$validatorEmail = new Zend_Validate_EmailAddress();
$validatorEmail->setMessage("ung&uuml;ltige Email Adresse", Zend_Validate_EmailAddress::INVALID);

$validatorAlnum = new Zend_Validate_Alnum(true);
$validatorAlnum->setMessage("es sind nur alphanumerische Werte erlaubt", Zend_Validate_Alnum::NOT_ALNUM);
$validatorAlnum->setMessage("Bitte f&uuml;llen sie dieses Feld aus", Zend_Validate_Alnum::STRING_EMPTY);

Nun kommt die Klasse Zend_Filter_Input zum Einsatz. Der Konstruktor ist hier etwas komplexer:

$input = new Zend_Filter_Input( $array_filter, $array_validators, $data, $options );

Für unser Beispiel ist so folgender Konstruktoraufruf notwendig:

$input = new Zend_Filter_Input(
// Filter
array(
'name' => new Zend_Filter_StringTrim(),
'email' => new Zend_Filter_StringTrim(),
'homepage' => new Zend_Filter_StringTrim(),
'message' => array( new Zend_Filter_StripTags(), new Zend_Filter_StringTrim() )
),

// validators
array(
'name' => $validatorAlnum,
'email' => $validatorEmail,
'homepage' => array( Zend_Filter_Input::ALLOW_EMPTY => true ),
'message' => array()
),

// data
$_POST,

// options
array(
Zend_Filter_Input::NOT_EMPTY_MESSAGE => "Bitte f&uuml;llen sie '%field%' aus",
Zend_Filter_Input::BREAK_CHAIN => false
)
);

Der erste Parameter enthält alle Filter. Es wird hierfür ein assoziatives Array mit dem jeweiligen Feldnamen und einem Filter erwartet. Werden mehrere Filter benötigt (siehe im Beispiel das Feld “message”) dann können auch mehrere Filter in einem Array übergeben werden.
Der zweite Parameter enthält alle Validatoren, auch hier wieder als assoziatives Array. Hier kann auch festgelegt werden ob ein Feld vorhanden sein muss oder optional ist (optionale Felder erhalten den Wert “Zend_Filter_Input::ALLOW_EMPTY => true”, per default sind alle angegebenen Felder Pflichteingaben)
Der dritte Parameter enthält die Daten, hier im einfachen Fall werden alle Formulardaten ($_POST) übergeben.
Der letzte Parameter enthält Optionen. Zend_Filter_Input::NOT_EMPTY_MESSAGE legt die Fehlermeldung fest, die erscheint wenn ein Feld nicht befüllt wurde. Zend_Filter_Input::BREAK_CHAIN => false besagt, dass im Falle eines Fehlers die Verarbeitung nicht abgebrochen wird, sondern alle anderen Felder ebenfalls validiert werden.

Nun kann mit der Methode isValid() die Eingabe geprüft werden:

if($input->isValid())
echo "Validierung erfolgreich ".$input->getEscaped("name");
else
$errors = $input->getMessages();

Mit der Methode getMessages() können ggf. die Fehlermeldungen abgeholt werden. Es handelt sich dabei um ein assoziatives Array aus Feldname => array( Fehlermeldung1, Fehlermeldung2, … ).

Für ein besseres Verständnis, gibt es hier ein komplettes Beispielskript zum Download. Es enthält über diese Anleitung hinaus noch den Code für eine Ausgabe der Fehlermeldungen und eine eigene Validierungsklasse, welche überprüft ob ein Name auch aus zwei Teilen besteht (z.B. Heinz Müller). Das macht zwar nicht viel Sinn, aber ergibt ein gutes Beispiel wie man selbst Validierungsklassen erstellt und nahtlos in diesen Vorgang einfügen kann.

Ähnliche Beiträge

  1. Zend Framework – ein Überblick

2 Kommentare zu “Tutorial – Formularverarbeitung mit dem Zend Framework”

  1. trady

    Hi Tobi,

    Im Moment hänge ich gerade an einem “Select”-Auswahlfeld, wo der Benutzer mehrere Werte auswählen kann.

    Sobald ich das Formular absende und die Funktion “validateAction” ausgeführt wird, erhalte ich die folgende Fehlermeldung:
    ‘Array’ was not found in the haystack

    Vielleicht kannst Du noch ein multiples “Select-Auswahlfeld mit in Dein Tutorial aufnehmen ?

    Grüsse,
    trady

     
  2. Geek

    Vorab, vielen Dank für das Tutorial hat mir schon gut geholfen. Also das Validieren vom SELECT hab ich noch nicht gemacht. Aber zum erstellen nehme ich Zend_Form_Element_Select und mit addMultiOptions füge ich die options an, hier übergebe ich ein key=>value arry und die keys sind bei mir numerisch, daher war mein erster ansatz mit Alnum zum validieren, aber natürlich muss ich es noch testen :)

     

Hinterlasse eine Antwort