Zend_Validate-WritingValidators.xml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15157 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.validate.writing_validators">
  5. <title>Schreiben von Prüfern</title>
  6. <para>
  7. Zend_Validate bietet ein Set von standardmäßig benötigten Prüfern, aber zwangsläufig, werden
  8. Entwickler wünschen, eigene Prüfer für die eigenen Bedürfnisse zu schreiben. Die Aufgabe des
  9. Schreibens eigener Prüfer wird in diesem Kapitel beschrieben.
  10. </para>
  11. <para>
  12. <classname>Zend_Validate_Interface</classname> definiert drei Methoden, <code>isValid()</code>,
  13. <code>getMessages()</code>, und <code>getErrors()</code>, welche von Benutzerklassen implementiert
  14. werden können um eigene Prüfobjekte zu erstellen. Ein Objekt welches das
  15. <classname>Zend_Validate_Interface</classname> Interface implementiert kann einer Prüfkette mit
  16. <classname>Zend_Validate::addValidator()</classname> hinzugefügt werden. Solche Objekte können auch mit
  17. <link linkend="zend.filter.input"><classname>Zend_Filter_Input</classname></link> verwendet werden.
  18. </para>
  19. <para>
  20. Wie man bereits aus der obigen Beschreibung von <classname>Zend_Validate_Interface</classname> folgern kann,
  21. geben die vom Zend Framework bereitgestellten Prüfklassen einen boolschen Wert zurück, ob die Prüfung
  22. des Wertes erfolgreich war oder nicht. Sie geben auch darüber Informationen
  23. <emphasis role="bold">warum</emphasis> ein Wert die Prüfung nicht bestanden hat. Die Verfügbarkeit der
  24. Gründe für fehlgeschlagene Prüfungen kann für eine Anwendung aus vielen Gründen nützlich sein, wie
  25. zum Beispiel das zur Verfügung stellen von Statistiken für Useability Analysen.
  26. </para>
  27. <para>
  28. Grundlegende Funktionalitäten für fehlgeschlagene Prüfmeldungen ist in <classname>Zend_Validate_Abstract</classname>
  29. implementiert. Um diese Funktionalität einzubinden wenn eine Prüfklasse erstellt wird, muß einfach
  30. <classname>Zend_Validate_Abstract</classname> erweitert werden. In der existierenden Klasse wird die Logik der
  31. <code>isValid()</code> Methode implementiert und die Variablen für die Nachrichten und
  32. Nachrichten-Templates definiert werden die zu den Typen von Prüffehlern passen die auftreten können.
  33. Wenn ein Wert die Prüfung nicht besteht, sollte <code>isValid()</code> <code>false</code> zurückgeben.
  34. Wenn der Wert die Prüfung besteht, sollte <code>isValid()</code> <code>true</code> zurückgeben.
  35. </para>
  36. <para>
  37. Normalerweise sollte die <code>isValid()</code> Methode keine Ausnahmen werfen, ausser wenn es unmöglich
  38. ist festzustellen ob ein Eingabewert gültig ist oder nicht. Einige Beispiele für gute Fälle in denen keine
  39. Ausnahme geworfen werden sollte sind, wenn eine Datei nicht geöffnet werden konnte, ein LDAP Server nicht
  40. erreicht wurde, oder eine Datenbank Verbindung unerreichbar ist, und wo solche Dinge für Prüfprozesse
  41. benötigt werden um zu erkennen ob die Prüfung gültig oder ungültig ist.
  42. </para>
  43. <example id="zend.validate.writing_validators.example.simple">
  44. <title>Erstellen einer einfachen Prüfklasse</title>
  45. <para>
  46. Das folgende Beispiel demonstriert wie ein sehr einfacher eigener Prüfer geschrieben werden könnte.
  47. In diesem Fall sind die Prüfregeln sehr einfach und der Eingabewert muß ein Gleitkommawert sein.
  48. <programlisting role="php"><![CDATA[
  49. class MyValid_Float extends Zend_Validate_Abstract
  50. {
  51. const FLOAT = 'float';
  52. protected $_messageTemplates = array(
  53. self::FLOAT => "'%value%' ist kein Gleitkommawert"
  54. );
  55. public function isValid($value)
  56. {
  57. $this->_setValue($value);
  58. if (!is_float($value)) {
  59. $this->_error();
  60. return false;
  61. }
  62. return true;
  63. }
  64. }
  65. ]]></programlisting>
  66. Die Klasse definiert ein Template für Ihre einzige Nachricht bei Prüfungsfehlern, welche den eingebauten
  67. magischen Parameter <code>%value%</code> inkludiert. Der Aufruf von <code>_setValue()</code> präpariert
  68. das Objekt den getesteten Wert automatisch in die Fehlernachricht einzufügen, wenn die Prüfung des Wertes
  69. fehlschlägt. Der Aufruf von <code>_error()</code> spürt den Grund für die fehlgeschlagene Prüfung auf.
  70. Da diee Klasse nur eine Fehlernachricht definiert, ist es nicht notwendig <code>_error()</code> den
  71. Namen des Templates der Fehlernachricht zu geben.
  72. </para>
  73. </example>
  74. <example id="zend.validate.writing_validators.example.conditions.dependent">
  75. <title>Schreiben einer Prüfklasse die abhängige Konditionen besitzt</title>
  76. <para>
  77. Das folgende Beispiel demonstriert ein komplexeres Set von Prüfregeln, wobei es notwendig ist das der
  78. Eingabewert nummerisch und innerhalb eines Bereiches von Mindest- und Maximalgrenzwerten ist. Bei einem
  79. Eingabewert würde die Prüfung wegen exakt einer der folgenden Gründe fehlschlagen:
  80. <itemizedlist>
  81. <listitem>
  82. <para>Der Eingabewert ist nicht nummerisch.</para>
  83. </listitem>
  84. <listitem>
  85. <para>Der Eingabewert ist kleiner als der minimal erlaubte Wert.</para>
  86. </listitem>
  87. <listitem>
  88. <para>Der Eingabewert ist größer als der maximal erlaubte Wert.</para>
  89. </listitem>
  90. </itemizedlist>
  91. </para>
  92. <para>
  93. Diese Gründe für fehlgeschlagene Prüfungen werden in Definitionen der Klasse übersetzt:
  94. <programlisting role="php"><![CDATA[
  95. class MyValid_NumericBetween extends Zend_Validate_Abstract
  96. {
  97. const MSG_NUMERIC = 'msgNumeric';
  98. const MSG_MINIMUM = 'msgMinimum';
  99. const MSG_MAXIMUM = 'msgMaximum';
  100. public $minimum = 0;
  101. public $maximum = 100;
  102. protected $_messageVariables = array(
  103. 'min' => 'minimum',
  104. 'max' => 'maximum'
  105. );
  106. protected $_messageTemplates = array(
  107. self::MSG_NUMERIC => "'%value%' ist nicht nummerisch",
  108. self::MSG_MINIMUM => "'%value%' muß mindestens '%min%' sein",
  109. self::MSG_MAXIMUM => "'%value%' darf nicht mehr als '%max%' sein"
  110. );
  111. public function isValid($value)
  112. {
  113. $this->_setValue($value);
  114. if (!is_numeric($value)) {
  115. $this->_error(self::MSG_NUMERIC);
  116. return false;
  117. }
  118. if ($value < $this->minimum) {
  119. $this->_error(self::MSG_MINIMUM);
  120. return false;
  121. }
  122. if ($value > $this->maximum) {
  123. $this->_error(self::MSG_MAXIMUM);
  124. return false;
  125. }
  126. return true;
  127. }
  128. }
  129. ]]></programlisting>
  130. Die öffentlichen Eigenschaften <code>$minimum</code> und <code>$maximum</code> wurden eingeführt um
  131. die Mindest- und Maximalgrenzen anzubieten, beziehungsweise, für einen Wert um die Prüfung erfolgreich
  132. zu bestehen. Die Klasse definiert auch zwei Nachrichtenvariablen die zu den öffentlichen Eigenschaften
  133. korrespondieren und es erlauben <code>min</code> und <code>max</code> in den Nachrichten Templates als
  134. magische Parameter zu verwenden, genauso wie <code>value</code>.
  135. </para>
  136. <para>
  137. Zu beachten ist, das wenn eine der Prüfungen in <code>isValid()</code> fehlschlägt, eine entsprechende
  138. Fehlernachricht vorbereitet wird, und die Methode sofort <code>false</code> zurückgibt. Diese
  139. Prüfregeln sind deswegen sequentiell abhängig. Das bedeuted, wenn einer der Tests fehlschlägt, gibt es
  140. keinen Grund eine weitere nachfolgende Prüfregel zu testen. Das muß aber trotzdem nicht der Fall sein.
  141. Das folgende Beispiel zeigt wie man eine Klasse schreiben kann die unabhängige Prüfregeln besitzt,
  142. wo die Prüfobjekte mehrfache Gründe zurückgeben könnten, warum ein spezieller Prüfversuch fehlgeschlagen
  143. ist.
  144. </para>
  145. </example>
  146. <example id="zend.validate.writing_validators.example.conditions.independent">
  147. <title>Prüfen mit unabhängigen Konditionen, mehrfache Gründe für Fehler</title>
  148. <para>
  149. Angenommen es wird eine Prüfklasse geschrieben für das Erzwingen von Passwortstärke - wenn ein Benutzer
  150. ein Passwort auswählen muß das diversen Kriterien entspricht um zu Helfen das die Benutzerzugänge
  151. sicher sind. Angenommen die Passwort Sicherheitskriterien erzwingen das folgende Passwort:
  152. <itemizedlist>
  153. <listitem>
  154. <para>mindestens 8 Zeichen Länge,</para>
  155. </listitem>
  156. <listitem>
  157. <para>enthält mindestens ein großgeschriebenes Zeichen,</para>
  158. </listitem>
  159. <listitem>
  160. <para>enthält mindestens ein kleingeschriebenes Zeichen,</para>
  161. </listitem>
  162. <listitem>
  163. <para>und enthält mindestens eine Ziffer.</para>
  164. </listitem>
  165. </itemizedlist>
  166. </para>
  167. <para>
  168. Die folgende Klasse impementiert diese Prüfkriterien:
  169. <programlisting role="php"><![CDATA[
  170. class MyValid_PasswordStrength extends Zend_Validate_Abstract
  171. {
  172. const LENGTH = 'length';
  173. const UPPER = 'upper';
  174. const LOWER = 'lower';
  175. const DIGIT = 'digit';
  176. protected $_messageTemplates = array(
  177. self::LENGTH => "'%value%' muß mindestens 8 Zeichen lang sein",
  178. self::UPPER => "'%value%' muß mindestens ein großgeschriebenes "
  179. . "Zeichen enthalten",
  180. self::LOWER => "'%value%' muß mindestens ein kleingeschriebenes "
  181. . "Zeichen enthalten",
  182. self::DIGIT => "'%value%' muß mindestens eine Ziffer enthalten"
  183. );
  184. public function isValid($value)
  185. {
  186. $this->_setValue($value);
  187. $isValid = true;
  188. if (strlen($value) < 8) {
  189. $this->_error(self::LENGTH);
  190. $isValid = false;
  191. }
  192. if (!preg_match('/[A-Z]/', $value)) {
  193. $this->_error(self::UPPER);
  194. $isValid = false;
  195. }
  196. if (!preg_match('/[a-z]/', $value)) {
  197. $this->_error(self::LOWER);
  198. $isValid = false;
  199. }
  200. if (!preg_match('/\d/', $value)) {
  201. $this->_error(self::DIGIT);
  202. $isValid = false;
  203. }
  204. return $isValid;
  205. }
  206. }
  207. ]]></programlisting>
  208. Zu beachten ist das diese vier Testkriterien in <code>isValid()</code> nicht sofort <code>false</code>
  209. zurückgeben. Das erlaubt der Prüfklasse <emphasis role="bold">alle</emphasis> Gründe anzubieten bei denen
  210. das Eingabepasswort den Prüfvoraussetzungen nicht entsprochen hat. Wenn, zum Beispiel, ein Benutzer
  211. den String "<code>#$%</code>" als Passwort angegeben hat, würde <code>isValid()</code> alle vier
  212. Prüfungfehlermeldungen zurückgeben bei einen nachfolgenden Aufruf von <code>getMessages()</code>.
  213. </para>
  214. </example>
  215. </sect1>
  216. <!--
  217. vim:se ts=4 sw=4 et:
  218. -->