Zend_Form-QuickStart.xml 18 KB

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