File: Zend_Validate-WritingValidators.xml

package info (click to toggle)
zendframework 1.12.9%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 133,584 kB
  • sloc: xml: 1,311,829; php: 570,173; sh: 170; makefile: 125; sql: 121
file content (274 lines) | stat: -rw-r--r-- 11,644 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
<?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>