2
0

Zend_Validate-WritingValidators.xml 11 KB

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