[ZF-10089] Zend_Log
[zend.git] / documentation / manual / zh / module_specs / Zend_Form-QuickStart.xml
blob2a2690e4a50a7834c044eee08594d4202a3c10af
1 <sect1 id="zend.form.quickstart">
2     <title>Zend_Form 快速起步 </title>
4     <para>
5         本快速起步指南覆盖使用 <code>Zend_Form</code> 创建、校验和解析表单的基础。
6     </para>
8     <sect2 id="zend.form.quickstart.create">
9         <title> 创建表单对象 </title>
11         <para>
12             创建表单对象非常简单:只要实现 <code>Zend_Form</code>:
13         </para>
15         <programlisting role="php"><![CDATA[<?php
16 $form = new Zend_Form;
17 ?>]]></programlisting>
19         <para>
20             对于高级用例,需要创建 <code>Zend_Form</code> 的子类,但对于简单的表单,程序可以用 <code>Zend_Form</code> 的对象来创建。
21         </para>
23         <para>
24             如果想指定表单的动作和方法(总是好主意),用 <code>setAction()</code> 和 <code>setMethod()</code> 来完成:
25         </para>
27         <programlisting role="php"><![CDATA[<?php
28 $form->setAction('/resource/process')
29      ->setMethod('post');
30 ?>]]></programlisting>
32         <para>
33             上述代码设置表单动作为部分 URL "/resource/process" 和表单方法为 HTTP POST,这将在解析的最后期间表现出来。
34         </para>
36         <para>
37             你可以通过使用 setAttrib() 或 setAttribs() 方法为 <code>&lt;form&gt;</code> 标签设置另外的 HTML 属性,例如:如果想设置 id, 则设置 "id" 属性:
38         </para>
40         <programlisting role="php"><![CDATA[<?php
41 $form->setAttrib('id', 'login');
42 ?>]]></programlisting>
43     </sect2>
45     <sect2 id="zend.form.quickstart.elements">
46         <title> 添加表单元素 </title>
48         <para>
49             没有元素,表单就什么都不是。<code>Zend_Form</code> 带有一些缺省的通过 <code>Zend_View</code> 助手解析 XHTML 的元素:
50         </para>
52         <itemizedlist>
53             <listitem><para>
54                 button
55             </para></listitem>
57             <listitem><para>
58                 checkbox (or many checkboxes at once with multiCheckbox)
59             </para></listitem>
61             <listitem><para>
62                 hidden
63             </para></listitem>
65             <listitem><para>
66                 image
67             </para></listitem>
69             <listitem><para>
70                 password
71             </para></listitem>
73             <listitem><para>
74                 radio
75             </para></listitem>
77             <listitem><para>
78                 reset
79             </para></listitem>
81             <listitem><para>
82                 select (both regular and multi-select types)
83             </para></listitem>
85             <listitem><para>
86                 submit
87             </para></listitem>
89             <listitem><para>
90                 text
91             </para></listitem>
93             <listitem><para>
94                 textarea
95             </para></listitem>
96         </itemizedlist>
98         <para>
99             有两个方法添加表单元素:实例化具体的元素并传递这些对象,或者传递元素类型并使 <code>Zend_Form</code> 实例化一个正确类型的对象。
100         </para>
102         <para>
103             一些例子:
104         </para>
106         <programlisting role="php"><![CDATA[<?php
107 // Instantiating an element and passing to the form object:
108 $form->addElement(new Zend_Form_Element_Text('username'));
110 // Passing a form element type to the form object:
111 $form->addElement('text', 'username');
112 ?>]]></programlisting>
114         <para>
115             缺省地,这些没有校验器和过滤器,你需要用最基本的校验器和可能的过滤器来配置元素。有三个方法:(a) 在传递元素给表单之前,(b) 通过用 <code>Zend_Form</code> 创建元素时传递的配置选项,(c) 从表单把元素拉出来并在以后配置。
116         </para>
118         <para>
119             让我们首先看看为一个具体的元素实例创建校验器。可以传递 <code>Zend_Validate_*</code> 对象,或校验器的名称:
120         </para>
122         <programlisting role="php"><![CDATA[<?php
123 $username = new Zend_Form_Element_Text('username');
125 // Passing a Zend_Validate_* object:
126 $username->addValidator(new Zend_Validate_Alnum());
128 // Passing a validator name:
129 $username->addValidator('alnum');
130 ?>]]></programlisting>
132         <para>
133             当使用第二个方法,如果校验器可接受构造器参数,可以把它们放到数组里作为第三个参数:
134         </para>
136         <programlisting role="php"><![CDATA[<?php
137 // Pass a pattern
138 $username->addValidator('regex', false, array('/^[a-z]/i'));
139 ?>]]></programlisting>
141         <para>
142             (第二个参数用来指示是否这个校验失败时停止后面的校验,缺省为 false。)
143         </para>
145         <para>
146             你也可能希望指定一个必需的元素,可以通过使用访问器或当创建该元素时传递一个选项来完成,在前面的例子中:
147         </para>
149         <programlisting role="php"><![CDATA[<?php
150 // 使这个元素成为必需:
151 $username->setRequired(true);
152 ?>]]></programlisting>
154         <para>
155             当一个元素是必需的,一个 'NotEmpty' 校验器被添加到校验器链的顶部,确保该元素有一个值。
156         </para>
158         <para>
159             过滤器会像校验器一样注册,为了演示,让我们添加一个来把最终值变小写的过滤器:
160         </para>
162         <programlisting role="php"><![CDATA[<?php
163 $username->addFilter('StringtoLower');
164 ?>]]></programlisting>
166         <para>
167             这样,最终元素设置看起来像这样:
168         </para>
170         <programlisting role="php"><![CDATA[<?php
171 $username->addValidator('alnum')
172          ->addValidator('regex', false, array('/^[a-z]/'))
173          ->setRequired(true)
174          ->addFilter('StringToLower');
176 // or, more compactly:
177 $username->addValidators(array('alnum',
178         array('regex', false, '/^[a-z]/i')
179     ))
180     ->setRequired(true)
181     ->addFilters(array('StringToLower'));
182 ?>]]></programlisting>
185         <para>
186             就算这样简单,在表单中为每个元素都做这样的工作也是单调乏味的。让我们试一试上述的方法(b),当使用工厂模式 <code>Zend_Form::addElement()</code> 创建一个新元素,我们可以可选地传递配置选项,包括校验器和过滤器。这样,可以简单地完成上述任务:
187         </para>
189         <programlisting role="php"><![CDATA[<?php
190 $form->addElement('text', 'username', array(
191     'validators' => array(
192         'alnum',
193         array('regex', false, '/^[a-z]/i')
194     ),
195     'required' => true,
196     'filters'  => array('StringToLower'),
198 ?>]]></programlisting>
200         <note><para>
201             如果你发现在许多地方用同样的选项来设置元素,可以考虑创建自己的 <code>Zend_Form_Element</code> 的子类并使用它,这样长远来说会减少很多打字的任务。
202         </para></note>
203     </sect2>
205     <sect2 id="zend.form.quickstart.render">
206         <title> 解析(Render)表单 </title>
208         <para>
209             解析表单很简单,大部分元素使用  <code>Zend_View</code> 助手来解析,这样需要视图对象来解析。除了这以外,还有两个方法:使用表单的 render() 方法或简单地 echo 它。
210         </para>
212         <programlisting role="php"><![CDATA[<?php
213 // Explicitly calling render(), and passing an optional view object:
214 echo $form->render($view);
216 // Assuming a view object has been previously set via setView():
217 echo $form;
218 ?>]]></programlisting>
220         <para>
221             缺省地,<code>Zend_Form</code> 和 <code>Zend_Form_Element</code> 将企图使用在 <code>ViewRenderer</code> 中初始化过的视图对象,你不需要在Zend Framework MVC 中手工设置视图。在视图脚本中解析表单是如此的简单:
222         </para>
224         <programlisting role="php"><![CDATA[
225 <?= $this->form ?>
226 ]]></programlisting>
228         <para>
229             在内部,<code>Zend_Form</code> 使用 "decorators" (装饰器) 来执行解析,这些装饰器可以替换内容、追加内容或预先准备内容,并拥有传递给它们的元素的 full introspection 。结果,你可以组合多个装饰器来完成定制效果。缺省地,<code>Zend_Form_Element</code> 实际上组合了四个装饰器来完成输出,参见下例的设置:
230         </para>
232         <programlisting role="php"><![CDATA[<?php
233 $element->addDecorators(array(
234     'ViewHelper',
235     'Errors',
236     array('HtmlTag', array('tag' => 'dd')),
237     array('Label', array('tag' => 'dt')),
239 ?>]]></programlisting>
241         <para>
242             ( &lt;HELPERNAME&gt; 是视图助手的名称,并根据元素不同而不同)
243         </para>
245         <para>
246             上述的例子创建的输出如下:
247         </para>
249         <programlisting role="html"><![CDATA[
250 <dt><label for="username" class="required">Username</dt>
251 <dd>
252     <input type="text" name="username" value="123-abc" />
253     <ul class="errors">
254         <li>'123-abc' has not only alphabetic and digit characters</li>
255         <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
256     </ul>
257 </dd>
258 ]]></programlisting>
260         <para>
261             (虽然没有使用相同的格式。)
262         </para>
264         <para>
265             如果你想输出不同的东西,可以修改由元素使用的装饰器,参见装饰器一节有更多内容。
266         </para>
268         <para>
269             表单循环检查所有元素,并把它们放到 HTML <code>&lt;form&gt;</code>。当设置表单时,你提供的动作和方法被提供给 <code>&lt;form&gt;</code> 标签,还有任何通过 <code>setAttribs()</code> 和它的家族设置的属性。
270         </para>
272         <para>
273             元素或者按注册的顺序循环,或者如果元素包含顺序属性,就按这个顺序循环。可以使用下列方法设置元素顺序:
274         </para>
276         <programlisting role="php"><![CDATA[<?php
277 $element->setOrder(10);
278 ?>]]></programlisting>
280         <para>
281             或者,当创建元素,作为一个选项传递给它:
282         </para>
284         <programlisting role="php"><![CDATA[<?php
285 $form->addElement('text', 'username', array('order' => 10));
286 ?>]]></programlisting>
287     </sect2>
289     <sect2 id="zend.form.quickstart.validate">
290         <title> 检查表单是否有效 </title>
292         <para>
293             表单提交之后,需要检查它是否能通过校验。每个元素根据提供的数据来检查,如果匹配元素名的键没有出现,并该条目被标记为必需,就用 null 值来校验。
294         </para>
296         <para>
297             数据从哪里来?用 <code>$_POST</code> 或 <code>$_GET</code> 或者其它手头上的数据源 (例如 web 服务请求):
298         </para>
300         <programlisting role="php"><![CDATA[<?php
301 if ($form->isValid($_POST)) {
302     // success!
303 } else {
304     // failure!
306 ?>]]></programlisting>
308         <para>
309             用 AJAX 请求, 有时候可以侥幸成功校验单个元素或一组元素。<code>isValidPartial()</code> 将校验局部的表单,不像 <code>isValid()</code>,如果特定的键没有出现,那个特定部分的元素就不校验:
310         </para>
312         <programlisting role="php"><![CDATA[<?php
313 if ($form->isValidPartial($_POST)) {
314     // elements present all passed validations
315 } else {
316     // one or more elements tested failed validations
318 ?>]]></programlisting>
320         <para>
321             一个可选的方法,<code>processAjax()</code>,也可以用来校验局部表单,不像 <code>isValidPartial()</code>,如果失败,它返回一个包含错误消息的 JSON 格式的字符串。
322         </para>
324         <para>
325             假设校验都通过,现在就可以取得过滤后的值:
326         </para>
328         <programlisting role="php"><![CDATA[<?php
329 $values = $form->getValues();
330 ?>]]></programlisting>
332         <para>
333             如果任何时候需要没有过滤的值,使用:
334         </para>
336         <programlisting role="php"><![CDATA[<?php
337 $unfiltered = $form->getUnfilteredValues();
338 ?>]]></programlisting>
339     </sect2>
341     <sect2 id="zend.form.quickstart.errorstatus">
342         <title> 获得错误状态 </title>
344         <para>
345             如果表单校验失败,在大多数情况下,可以再次解析表单,如果使用了缺省的装饰器,错误信息就会显示出来:
346         </para>
348         <programlisting role="php"><![CDATA[<?php
349 if (!$form->isValid($_POST)) {
350     echo $form;
352     // or assign to the view object and render a view...
353     $this->view->form = $form;
354     return $this->render('form');
356 ?>]]></programlisting>
358         <para>
359             如果想插入错误消息,有两个方法: <code>getErrors()</code> 返回一个元素名/代码对的联合数组(这里的代码是指一个错误代码数组)。<code>getMessages()</code> 返回一个元素名/消息对的联合数组(这里的消息是指错误代码/错误消息对的联合数组)。如果给定的元素没有任何错误,数组就不包含它。
360         </para>
361     </sect2>
363     <sect2 id="zend.form.quickstart.puttingtogether">
364         <title> 放到一起 </title>
366         <para>
367             来创建一个简单的登录表单,我们需要这些元素:
368         </para>
370         <itemizedlist>
371             <listitem><para>username</para></listitem>
372             <listitem><para>password</para></listitem>
373             <listitem><para>submit</para></listitem>
374         </itemizedlist>
376         <para>
377             让我们假设有效的用户名应当只是字母数字字符,以字母开头,最少 6 个字符,最长 20 个字符,最后格式化成小写;密码最少 6 个字符,当完成这些,我们就提交,保持未校验。
378         </para>
380         <para>
381             我们使用 <code>Zend_Form</code> 的配置选项的能力来建立表单:
382         </para>
384         <programlisting role="php"><![CDATA[<?php
387 $form = new Zend_Form();
388 $form->setAction('/user/login')
389      ->setMethod('post');
391 // Create and configure username element:
392 $username = $form->createElement('text', 'username');
393 $username->addValidator('alnum')
394          ->addValidator('regex', false, array('/^[a-z]+/'))
395          ->addValidator('stringLength', false, array(6, 20))
396          ->setRequired(true)
397          ->addFilter('StringToLower');
399 // Create and configure password element:
400 $password = $form->createElement('password', 'password');
401 $password->addValidator('StringLength', false, array(6))
402          ->setRequired(true);
404 // Add elements to form:
405 $form->addElement($username)
406      ->addElement($password)
407      // use addElement() as a factory to create 'Login' button:
408      ->addElement('submit', 'login', array('label' => 'Login'));
409 ?>]]></programlisting>
411         <para>
412             接着,我们将创建控制器来处理这些:
413         </para>
415         <programlisting role="php"><![CDATA[<?php
416 class UserController extends Zend_Controller_Action
418     public function getForm()
419     {
420         // create form as above
421         return $form;
422     }
424     public function indexAction()
425     {
426         // render user/form.phtml
427         $this->view->form = $this->getForm();
428         $this->render('form');
429     }
431     public function loginAction()
432     {
433         if (!$this->getRequest()->isPost()) {
434             return $this->_forward('index');
435         }
436         $form = $this->getForm();
437         if (!$form->isValid($_POST)) {
438             // Failed validation; redisplay form
439             $this->view->form = $form;
440             return $this->render('form');
441         }
443         $values = $form->getValues();
444         // now try and authenticate....
445     }
447 ?>]]></programlisting>
449         <para>
450             和一个视图脚本来显示表单:
451         </para>
453 <programlisting role="php"><![CDATA[
454 <h2>Please login:</h2>
455 <?= $this->form ?>
456 ]]></programlisting>
458         <para>
459             注意在控制器代码中,还有很多需要做:例如在提交后,需要用 <code>Zend_Auth</code> 来认证。
460         </para>
461     </sect2>
463     <sect2 id="zend.form.quickstart.config">
464         <title> 使用 Zend_Config 对象 </title>
466         <para>
467             所有 <code>Zend_Form</code> 类可以用 <code>Zend_Config</code> 来配置,可以传递 <code>Zend_Config</code> 对象给构造器或者通过 <code>setConfig()</code> 来传递。来看一下如何用 INI 文件来创建上述表单,首先,遵循建议,把配置放到反映发行位置的节里面,并集中到 'development' 节,接着,为给定控制器('user')设置一个节,为表单('login')设置一个键:
468         </para>
470         <programlisting role="ini"><![CDATA[
471 [development]
472 ; general form metainformation
473 user.login.action = "/user/login"
474 user.login.method = "post"
476 ; username element
477 user.login.elements.username.type = "text"
478 user.login.elements.username.options.validators.alnum.validator = "alnum"
479 user.login.elements.username.options.validators.regex.validator = "regex"
480 user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
481 user.login.elements.username.options.validators.strlen.validator = "StringLength"
482 user.login.elements.username.options.validators.strlen.options.min = "6"
483 user.login.elements.username.options.validators.strlen.options.max = "20"
484 user.login.elements.username.options.required = true
485 user.login.elements.username.options.filters.lower.filter = "StringToLower"
487 ; password element
488 user.login.elements.password.type = "password"
489 user.login.elements.password.options.validators.strlen.validator = "StringLength"
490 user.login.elements.password.options.validators.strlen.options.min = "6"
491 user.login.elements.password.options.required = true
493 ; submit element
494 user.login.elements.submit.type = "submit"
495 ]]></programlisting>
497         <para>
498             接着,你可以把它传递给表单构造器:
499         </para>
501         <programlisting role="php"><![CDATA[<?php
502 $config = new Zend_Config_Ini($configFile, 'development');
503 $form   = new Zend_Form($config->user->login);
504 ?>]]></programlisting>
506         <para>
507             整个表单就定义好了。
508         </para>
509     </sect2>
511     <sect2 id="zend.form.quickstart.conclusion">
512         <title> 结论 </title>
514         <para>
515             希望通过这个小教程,你能接触和理解 <code>Zend_Form</code> 的强大和灵活性,然后接着读更深的资料!
516         </para>
517     </sect2>
518 </sect1>
519 <!--
520 vim:se ts=4 sw=4 et: