| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.validate.writing_validators">
- <title>Schreiben von Prüfern</title>
- <para>
- <classname>Zend_Validate</classname> 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 zwei Methoden,
- <methodname>isValid()</methodname> und <methodname>getMessages()</methodname>, 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 <methodname>Zend_Validate::addValidator()</methodname> 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>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 <methodname>isValid()</methodname> 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
- <methodname>isValid()</methodname> <constant>FALSE</constant> zurückgeben. Wenn der Wert die
- Prüfung besteht, sollte <methodname>isValid()</methodname> <constant>TRUE</constant>
- zurückgeben.
- </para>
- <para>
- Normalerweise sollte die <methodname>isValid()</methodname> 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 <acronym>LDAP</acronym> 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.
- </para>
- <programlisting language="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>
- <para>
- Die Klasse definiert ein Template für Ihre einzige Nachricht bei Prüfungsfehlern, welche
- den eingebauten magischen Parameter <emphasis>%value%</emphasis> inkludiert. Der Aufruf
- von <methodname>_setValue()</methodname> präpariert das Objekt den getesteten Wert
- automatisch in die Fehlernachricht einzufügen, wenn die Prüfung des Wertes fehlschlägt.
- Der Aufruf von <methodname>_error()</methodname> spürt den Grund für die fehlgeschlagene
- Prüfung auf. Da diese Klasse nur eine Fehlernachricht definiert, ist es nicht notwendig
- <methodname>_error()</methodname> 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:
- </para>
- <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>
- Diese Gründe für fehlgeschlagene Prüfungen werden in Definitionen der Klasse übersetzt:
- </para>
- <programlisting language="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>
- <para>
- Die öffentlichen Eigenschaften <varname>$minimum</varname> und
- <varname>$maximum</varname> 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 <property>min</property> und <property>max</property> in
- den Nachrichten Templates als magische Parameter zu verwenden, genauso wie
- <property>value</property>.
- </para>
- <para>
- Zu beachten ist, das wenn eine der Prüfungen in <methodname>isValid()</methodname>
- fehlschlägt, eine entsprechende Fehlernachricht vorbereitet wird, und die Methode sofort
- <constant>FALSE</constant> 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:
- </para>
- <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>
- Die folgende Klasse impementiert diese Prüfkriterien:
- </para>
- <programlisting language="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>
- <para>
- Zu beachten ist das diese vier Testkriterien in <methodname>isValid()</methodname> nicht
- sofort <constant>FALSE</constant> zurückgeben. Das erlaubt der Prüfklasse
- <emphasis>alle</emphasis> Gründe anzubieten bei denen das Eingabepasswort
- den Prüfvoraussetzungen nicht entsprochen hat. Wenn, zum Beispiel, ein Benutzer den
- String "#$%" als Passwort angegeben hat, würde
- <methodname>isValid()</methodname> alle vier Prüfungfehlermeldungen zurückgeben bei
- einen nachfolgenden Aufruf von <methodname>getMessages()</methodname>.
- </para>
- </example>
- </sect1>
|