| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15157 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.validate.writing_validators">
- <title>Schreiben von Prüfern</title>
- <para>
- Zend_Validate bietet ein Set von standardmäßig benötigten Prüfern, aber zwangsläufig, werden
- Entwickler wünschen, eigene Prüfer für die eigenen Bedürfnisse zu schreiben. Die Aufgabe des
- Schreibens eigener Prüfer wird in diesem Kapitel beschrieben.
- </para>
- <para>
- <classname>Zend_Validate_Interface</classname> definiert drei Methoden, <code>isValid()</code>,
- <code>getMessages()</code>, und <code>getErrors()</code>, welche von Benutzerklassen implementiert
- werden können um eigene Prüfobjekte zu erstellen. Ein Objekt welches das
- <classname>Zend_Validate_Interface</classname> Interface implementiert kann einer Prüfkette mit
- <classname>Zend_Validate::addValidator()</classname> hinzugefügt werden. Solche Objekte können auch mit
- <link linkend="zend.filter.input"><classname>Zend_Filter_Input</classname></link> verwendet werden.
- </para>
- <para>
- Wie man bereits aus der obigen Beschreibung von <classname>Zend_Validate_Interface</classname> folgern kann,
- geben die vom Zend Framework bereitgestellten Prüfklassen einen boolschen Wert zurück, ob die Prüfung
- des Wertes erfolgreich war oder nicht. Sie geben auch darüber Informationen
- <emphasis role="bold">warum</emphasis> ein Wert die Prüfung nicht bestanden hat. Die Verfügbarkeit der
- Gründe für fehlgeschlagene Prüfungen kann für eine Anwendung aus vielen Gründen nützlich sein, wie
- zum Beispiel das zur Verfügung stellen von Statistiken für Useability Analysen.
- </para>
- <para>
- Grundlegende Funktionalitäten für fehlgeschlagene Prüfmeldungen ist in <classname>Zend_Validate_Abstract</classname>
- implementiert. Um diese Funktionalität einzubinden wenn eine Prüfklasse erstellt wird, muß einfach
- <classname>Zend_Validate_Abstract</classname> erweitert werden. In der existierenden Klasse wird die Logik der
- <code>isValid()</code> Methode implementiert und die Variablen für die Nachrichten und
- Nachrichten-Templates definiert werden die zu den Typen von Prüffehlern passen die auftreten können.
- Wenn ein Wert die Prüfung nicht besteht, sollte <code>isValid()</code> <code>false</code> zurückgeben.
- Wenn der Wert die Prüfung besteht, sollte <code>isValid()</code> <code>true</code> zurückgeben.
- </para>
- <para>
- Normalerweise sollte die <code>isValid()</code> Methode keine Ausnahmen werfen, ausser wenn es unmöglich
- ist festzustellen ob ein Eingabewert gültig ist oder nicht. Einige Beispiele für gute Fälle in denen keine
- Ausnahme geworfen werden sollte sind, wenn eine Datei nicht geöffnet werden konnte, ein LDAP Server nicht
- erreicht wurde, oder eine Datenbank Verbindung unerreichbar ist, und wo solche Dinge für Prüfprozesse
- benötigt werden um zu erkennen ob die Prüfung gültig oder ungültig ist.
- </para>
- <example id="zend.validate.writing_validators.example.simple">
- <title>Erstellen einer einfachen Prüfklasse</title>
- <para>
- Das folgende Beispiel demonstriert wie ein sehr einfacher eigener Prüfer geschrieben werden könnte.
- In diesem Fall sind die Prüfregeln sehr einfach und der Eingabewert muß ein Gleitkommawert sein.
- <programlisting role="php"><![CDATA[
- class MyValid_Float extends Zend_Validate_Abstract
- {
- const FLOAT = 'float';
- protected $_messageTemplates = array(
- self::FLOAT => "'%value%' ist kein Gleitkommawert"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- if (!is_float($value)) {
- $this->_error();
- return false;
- }
- return true;
- }
- }
- ]]></programlisting>
- Die Klasse definiert ein Template für Ihre einzige Nachricht bei Prüfungsfehlern, welche den eingebauten
- magischen Parameter <code>%value%</code> inkludiert. Der Aufruf von <code>_setValue()</code> präpariert
- das Objekt den getesteten Wert automatisch in die Fehlernachricht einzufügen, wenn die Prüfung des Wertes
- fehlschlägt. Der Aufruf von <code>_error()</code> spürt den Grund für die fehlgeschlagene Prüfung auf.
- Da diee Klasse nur eine Fehlernachricht definiert, ist es nicht notwendig <code>_error()</code> den
- Namen des Templates der Fehlernachricht zu geben.
- </para>
- </example>
- <example id="zend.validate.writing_validators.example.conditions.dependent">
- <title>Schreiben einer Prüfklasse die abhängige Konditionen besitzt</title>
- <para>
- Das folgende Beispiel demonstriert ein komplexeres Set von Prüfregeln, wobei es notwendig ist das der
- Eingabewert nummerisch und innerhalb eines Bereiches von Mindest- und Maximalgrenzwerten ist. Bei einem
- Eingabewert würde die Prüfung wegen exakt einer der folgenden Gründe fehlschlagen:
- <itemizedlist>
- <listitem>
- <para>Der Eingabewert ist nicht nummerisch.</para>
- </listitem>
- <listitem>
- <para>Der Eingabewert ist kleiner als der minimal erlaubte Wert.</para>
- </listitem>
- <listitem>
- <para>Der Eingabewert ist größer als der maximal erlaubte Wert.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Diese Gründe für fehlgeschlagene Prüfungen werden in Definitionen der Klasse übersetzt:
- <programlisting role="php"><![CDATA[
- class MyValid_NumericBetween extends Zend_Validate_Abstract
- {
- const MSG_NUMERIC = 'msgNumeric';
- const MSG_MINIMUM = 'msgMinimum';
- const MSG_MAXIMUM = 'msgMaximum';
- public $minimum = 0;
- public $maximum = 100;
- protected $_messageVariables = array(
- 'min' => 'minimum',
- 'max' => 'maximum'
- );
- protected $_messageTemplates = array(
- self::MSG_NUMERIC => "'%value%' ist nicht nummerisch",
- self::MSG_MINIMUM => "'%value%' muß mindestens '%min%' sein",
- self::MSG_MAXIMUM => "'%value%' darf nicht mehr als '%max%' sein"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- if (!is_numeric($value)) {
- $this->_error(self::MSG_NUMERIC);
- return false;
- }
- if ($value < $this->minimum) {
- $this->_error(self::MSG_MINIMUM);
- return false;
- }
- if ($value > $this->maximum) {
- $this->_error(self::MSG_MAXIMUM);
- return false;
- }
- return true;
- }
- }
- ]]></programlisting>
- Die öffentlichen Eigenschaften <code>$minimum</code> und <code>$maximum</code> wurden eingeführt um
- die Mindest- und Maximalgrenzen anzubieten, beziehungsweise, für einen Wert um die Prüfung erfolgreich
- zu bestehen. Die Klasse definiert auch zwei Nachrichtenvariablen die zu den öffentlichen Eigenschaften
- korrespondieren und es erlauben <code>min</code> und <code>max</code> in den Nachrichten Templates als
- magische Parameter zu verwenden, genauso wie <code>value</code>.
- </para>
- <para>
- Zu beachten ist, das wenn eine der Prüfungen in <code>isValid()</code> fehlschlägt, eine entsprechende
- Fehlernachricht vorbereitet wird, und die Methode sofort <code>false</code> zurückgibt. Diese
- Prüfregeln sind deswegen sequentiell abhängig. Das bedeuted, wenn einer der Tests fehlschlägt, gibt es
- keinen Grund eine weitere nachfolgende Prüfregel zu testen. Das muß aber trotzdem nicht der Fall sein.
- Das folgende Beispiel zeigt wie man eine Klasse schreiben kann die unabhängige Prüfregeln besitzt,
- wo die Prüfobjekte mehrfache Gründe zurückgeben könnten, warum ein spezieller Prüfversuch fehlgeschlagen
- ist.
- </para>
- </example>
- <example id="zend.validate.writing_validators.example.conditions.independent">
- <title>Prüfen mit unabhängigen Konditionen, mehrfache Gründe für Fehler</title>
- <para>
- Angenommen es wird eine Prüfklasse geschrieben für das Erzwingen von Passwortstärke - wenn ein Benutzer
- ein Passwort auswählen muß das diversen Kriterien entspricht um zu Helfen das die Benutzerzugänge
- sicher sind. Angenommen die Passwort Sicherheitskriterien erzwingen das folgende Passwort:
- <itemizedlist>
- <listitem>
- <para>mindestens 8 Zeichen Länge,</para>
- </listitem>
- <listitem>
- <para>enthält mindestens ein großgeschriebenes Zeichen,</para>
- </listitem>
- <listitem>
- <para>enthält mindestens ein kleingeschriebenes Zeichen,</para>
- </listitem>
- <listitem>
- <para>und enthält mindestens eine Ziffer.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Die folgende Klasse impementiert diese Prüfkriterien:
- <programlisting role="php"><![CDATA[
- class MyValid_PasswordStrength extends Zend_Validate_Abstract
- {
- const LENGTH = 'length';
- const UPPER = 'upper';
- const LOWER = 'lower';
- const DIGIT = 'digit';
- protected $_messageTemplates = array(
- self::LENGTH => "'%value%' muß mindestens 8 Zeichen lang sein",
- self::UPPER => "'%value%' muß mindestens ein großgeschriebenes "
- . "Zeichen enthalten",
- self::LOWER => "'%value%' muß mindestens ein kleingeschriebenes "
- . "Zeichen enthalten",
- self::DIGIT => "'%value%' muß mindestens eine Ziffer enthalten"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- $isValid = true;
- if (strlen($value) < 8) {
- $this->_error(self::LENGTH);
- $isValid = false;
- }
- if (!preg_match('/[A-Z]/', $value)) {
- $this->_error(self::UPPER);
- $isValid = false;
- }
- if (!preg_match('/[a-z]/', $value)) {
- $this->_error(self::LOWER);
- $isValid = false;
- }
- if (!preg_match('/\d/', $value)) {
- $this->_error(self::DIGIT);
- $isValid = false;
- }
- return $isValid;
- }
- }
- ]]></programlisting>
- Zu beachten ist das diese vier Testkriterien in <code>isValid()</code> nicht sofort <code>false</code>
- zurückgeben. Das erlaubt der Prüfklasse <emphasis role="bold">alle</emphasis> Gründe anzubieten bei denen
- das Eingabepasswort den Prüfvoraussetzungen nicht entsprochen hat. Wenn, zum Beispiel, ein Benutzer
- den String "<code>#$%</code>" als Passwort angegeben hat, würde <code>isValid()</code> alle vier
- Prüfungfehlermeldungen zurückgeben bei einen nachfolgenden Aufruf von <code>getMessages()</code>.
- </para>
- </example>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|