Zend_Form-QuickStart.xml 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. <sect1 id="zend.form.quickstart">
  2. <title>Zend_Form - Быстрый старт</title>
  3. <para>
  4. Данное руководство охватывает основы создания форм,
  5. проверки корректности данных и визуализиции с использованием
  6. <code>Zend_Form</code>.
  7. </para>
  8. <sect2 id="zend.form.quickstart.create">
  9. <title>Создание объекта формы</title>
  10. <para>
  11. Объекты форм создаются через простое инстанцирование
  12. <code>Zend_Form</code>:
  13. </para>
  14. <programlisting language="php"><![CDATA[
  15. $form = new Zend_Form;
  16. ]]>
  17. </programlisting>
  18. <para>
  19. Для более сложных случаев использования вы можете создавать
  20. подклассы <code>Zend_Form</code>, но простые формы вы можете
  21. создавать, используя объект <code>Zend_Form</code>.
  22. </para>
  23. <para>
  24. Если вы хотите указать атрибуты <code>action</code> и
  25. <code>method</code> (что во всех случаях является хорошей идеей), то
  26. можете сделать это с использованием аксессоров
  27. <code>setAction()</code> и <code>setMethod()</code>:
  28. </para>
  29. <programlisting language="php"><![CDATA[
  30. $form->setAction('/resource/process')
  31. ->setMethod('post');
  32. ]]>
  33. </programlisting>
  34. <para>
  35. Приведенный выше код устанавливает значение атрибута
  36. <code>action</code> равным "/resource/process" и указывает способ
  37. отправки данных - HTTP POST. Эти атрибуты будут выведены после
  38. окончательного рендеринга формы.
  39. </para>
  40. <para>
  41. Вы можете установить дополнительные HTML-атрибуты для тега
  42. <code>&lt;form&gt;</code>, используя методы <code>setAttrib()</code>
  43. и <code>setAttribs()</code>. Например, если нужно установить
  44. идентификатор элемента формы, то установите атрибут "id":
  45. </para>
  46. <programlisting language="php"><![CDATA[
  47. $form->setAttrib('id', 'login');
  48. ]]>
  49. </programlisting>
  50. </sect2>
  51. <sect2 id="zend.form.quickstart.elements">
  52. <title>Добавление элементов в форму</title>
  53. <para>
  54. Форма без элементов бесмысленна. <code>Zend_Form</code>
  55. поставляется с некоторым начальным набором элементов, которые
  56. отвечают за рендеринг XHTML-кода с использованием помощников
  57. <code>Zend_View</code>. В этот список входят элементы:
  58. </para>
  59. <itemizedlist>
  60. <listitem><para>
  61. button (кнопка)
  62. </para></listitem>
  63. <listitem><para>
  64. checkbox (флажок опций, или несколько флажков опций
  65. через multiCheckbox)
  66. </para></listitem>
  67. <listitem><para>
  68. hidden (спрятанное поле)
  69. </para></listitem>
  70. <listitem><para>
  71. image (изображение)
  72. </para></listitem>
  73. <listitem><para>
  74. password (пароль)
  75. </para></listitem>
  76. <listitem><para>
  77. radio (переключатель)
  78. </para></listitem>
  79. <listitem><para>
  80. reset (кнопка сброса)
  81. </para></listitem>
  82. <listitem><para>
  83. select (выпадающий список - как обычный, так multi-select)
  84. </para></listitem>
  85. <listitem><para>
  86. submit (кнопка отправки)
  87. </para></listitem>
  88. <listitem><para>
  89. text (текстовое поле)
  90. </para></listitem>
  91. <listitem><para>
  92. textarea (текстовая область)
  93. </para></listitem>
  94. </itemizedlist>
  95. <para>
  96. Есть два способа добавления элементов в форму - вы можете
  97. инстанцировать нужные элементы и передавать их объекту формы, или
  98. передавать только тип элемента, в этом случае <code>Zend_Form</code>
  99. инстанцирует соответствующий объект за вас.
  100. </para>
  101. <para>
  102. Некоторые примеры:
  103. </para>
  104. <programlisting language="php"><![CDATA[
  105. // Инстанцирование элемента и его передача объекту формы:
  106. $form->addElement(new Zend_Form_Element_Text('username'));
  107. // Передача типа элемента объекту формы
  108. $form->addElement('text', 'username');
  109. ]]>
  110. </programlisting>
  111. <para>
  112. По умолчанию элементы не имеют никаких валидаторов или фильтров. Это
  113. означает, что вам нужно установить к своим элементам, как минимум,
  114. валидаторы, и, возможно, фильтры. Вы можете делать это (a) до
  115. передачи элементов в форму, (b) через опции конфигурирования,
  116. которые передаются при создании элемента через
  117. <code>Zend_Form</code>, или (с) путем извлечения элементов формы из
  118. объекта формы и их конфигурирования.
  119. </para>
  120. <para>
  121. Сначала рассмотрим создание валидаторов для конкретного объекта
  122. элемента. Вы можете передавать объекты <code>Zend_Validate_*</code>
  123. или имена валидаторов:
  124. </para>
  125. <programlisting language="php"><![CDATA[
  126. $username = new Zend_Form_Element_Text('username');
  127. // Передача объекта Zend_Validate_*:
  128. $username->addValidator(new Zend_Validate_Alnum());
  129. // Передача имени валидатора:
  130. $username->addValidator('alnum');
  131. ]]></programlisting>
  132. <para>
  133. В случае использования второго варианта, если валидатор принимает
  134. аргументы конструктора, то вы можете передавать их через массив как
  135. третий параметр:
  136. </para>
  137. <programlisting language="php"><![CDATA[
  138. // Передача шаблона
  139. $username->addValidator('regex', false, array('/^[a-z]/i'));
  140. ]]>
  141. </programlisting>
  142. <para>
  143. (Второй параметр используется для указания того, должен ли валидатор
  144. в том случае, если данные не прошли проверку, прерывать дальнейшую
  145. проверку в цепочке валидаторов; по умолчанию он равен false.)
  146. </para>
  147. <para>
  148. Вы можете также указать элемент как обязательный для заполнения. Это
  149. может быть сделано как с помощью аксессора, так и путем
  150. передачи определенной опции при создании элемента. В первом случае:
  151. </para>
  152. <programlisting language="php"><![CDATA[
  153. // Указание того, что элемент обязателен для заполнения:
  154. $username->setRequired(true);
  155. ]]>
  156. </programlisting>
  157. <para>
  158. Если элемент обязателен для заполнения, то в начало цепочки
  159. валидаторов добавляется валидатор 'NotEmpty', который проверяет,
  160. имеет ли элемент значение.
  161. </para>
  162. <para>
  163. Фильтры регистрируются в основном так же, как и валидаторы. Для
  164. демонстрации добавим фильтр для приведения значения к
  165. нижнему регистру:
  166. </para>
  167. <programlisting language="php"><![CDATA[
  168. $username->addFilter('StringToLower');
  169. ]]>
  170. </programlisting>
  171. <para>
  172. Таким образом, окончательно установка элемента получится
  173. такой, как показано ниже:
  174. </para>
  175. <programlisting language="php"><![CDATA[
  176. $username->addValidator('alnum')
  177. ->addValidator('regex', false, array('/^[a-z]/'))
  178. ->setRequired(true)
  179. ->addFilter('StringToLower');
  180. // или в более компактной форме:
  181. $username->addValidators(array('alnum',
  182. array('regex', false, '/^[a-z]/i')
  183. ))
  184. ->setRequired(true)
  185. ->addFilters(array('StringToLower'));
  186. ]]>
  187. </programlisting>
  188. <para>
  189. Выполнение этих действий для каждого элемента по отдельности может
  190. показаться несколько утомительным. Попробуем вариант (b) из
  191. перечисленных выше. Когда мы создаем новый элемент, используя
  192. <code>Zend_Form::addElement()</code> в качестве фабрики, то можем
  193. опционально передавать опции конфигурирования. Они могут включать в
  194. себя валидаторы и фильтры для использования. Таким образом, чтобы
  195. неявным образом сделать все это, попробуйте следующее:
  196. </para>
  197. <programlisting language="php"><![CDATA[
  198. $form->addElement('text', 'username', array(
  199. 'validators' => array(
  200. 'alnum',
  201. array('regex', false, '/^[a-z]/i')
  202. ),
  203. 'required' => true,
  204. 'filters' => array('StringToLower'),
  205. ));
  206. ]]>
  207. </programlisting>
  208. <note><para>
  209. Если вы обнаружили, что настраиваете элементы, используя одни и те
  210. же опции во многих местах, то можете создать подкласс
  211. <code>Zend_Form_Element</code> и использовать его вместо выполнения
  212. этих процедур; это может избавить от лишней работы по набору кода.
  213. </para></note>
  214. </sect2>
  215. <sect2 id="zend.form.quickstart.render">
  216. <title>Визуализация формы</title>
  217. <para>
  218. Визуализация формы производится легко. Большинство элементов
  219. использует помощника <code>Zend_View</code> для генерации вывода и
  220. поэтому нуждаются в объекте вида для выполнения рендеринга. Есть
  221. два способа запустить рендеринг: использовать метод формы render()
  222. или просто вывести форму с помощью echo.
  223. </para>
  224. <programlisting language="php"><![CDATA[
  225. // Явный вызов render() с передачей объекта вида:
  226. echo $form->render($view);
  227. // Предполагается, что объект вида уже был установлен ранее через setView():
  228. echo $form;
  229. ]]>
  230. </programlisting>
  231. <para>
  232. По умолчанию <code>Zend_Form</code> будет пытаться использовать
  233. объект вида, инициализированный в <code>ViewRenderer</code>, это
  234. означает, что вам не нужно будет вручную устанавливать объект вида
  235. при использовании MVC Zend Framework-а. Код для визуализации формы
  236. в скрипте вида весьма прост:
  237. </para>
  238. <programlisting language="php"><![CDATA[
  239. <?php echo $this->form ?>
  240. ]]>
  241. </programlisting>
  242. <para>
  243. Внутри себя <code>Zend_Form</code> использует "декораторы" для
  244. выполнения визуализации. Эти декораторы могут замещать содержимое
  245. переданного элемента, производить добавления в его начало и конец,
  246. производить наблюдение за ним. В результате вы можете комбинировать
  247. несколько декораторов для достижения нужного эффекта. По умолчанию
  248. в <code>Zend_Form_Element</code> используется четыре декоратора
  249. для получения нужного вывода; их установка выглядит приблизительно
  250. так:
  251. </para>
  252. <programlisting language="php"><![CDATA[
  253. $element->addDecorators(array(
  254. 'ViewHelper',
  255. 'Errors',
  256. array('HtmlTag', array('tag' => 'dd')),
  257. array('Label', array('tag' => 'dt')),
  258. ));
  259. ]]>
  260. </programlisting>
  261. <para>
  262. Код выше создает вывод наподобие следующего:
  263. </para>
  264. <programlisting language="html"><![CDATA[
  265. <dt><label for="username" class="required">Username</dt>
  266. <dd>
  267. <input type="text" name="username" value="123-abc" />
  268. <ul class="errors">
  269. <li>'123-abc' has not only alphabetic and digit characters</li>
  270. <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
  271. </ul>
  272. </dd>
  273. ]]>
  274. </programlisting>
  275. <para>
  276. Вы можете изменить набор декораторов, используемый элементом, если
  277. хотите иметь другой результат вывода; более подробную информацию
  278. читайте в разделе о декораторах.
  279. </para>
  280. <para>
  281. Форма сама по себе просто производит обход содержащегося в ней
  282. списка элементов и окружает получившийся вывод тегами
  283. <code>&lt;form&gt;</code>. Переданные вами <code>action</code> и
  284. <code>method</code> устанавливаются в качестве атрибутов тега
  285. <code>&lt;form&gt;</code> - так же, как и остальные атрибуты,
  286. установленные через семейство методов
  287. <code>setAttribs()</code>.
  288. </para>
  289. <para>
  290. Элементы обходятся в том же порядке, в котором они были
  291. зарегистрированы, но если ваш элемент содержит атрибут order, то он
  292. используется для сортировки. Вы можете установить порядок элемента,
  293. используя:
  294. </para>
  295. <programlisting language="php"><![CDATA[
  296. $element->setOrder(10);
  297. ]]>
  298. </programlisting>
  299. <para>
  300. Или путем передачи в качестве опции при создании элемента:
  301. </para>
  302. <programlisting language="php"><![CDATA[
  303. $form->addElement('text', 'username', array('order' => 10));
  304. ]]>
  305. </programlisting>
  306. </sect2>
  307. <sect2 id="zend.form.quickstart.validate">
  308. <title>Проверка корректности данных формы</title>
  309. <para>
  310. После того, как получены данные формы, нужно их проверить
  311. и выяснить, правильно ли заполнена форма. Для всех элементов
  312. производится проверка переданных
  313. данных на наличие ключа, соответствующего имени элемента. Если этот
  314. ключ не найден, и элемент при этом помечен как обязательный, то для
  315. проверки на корректность используется значение null.
  316. </para>
  317. <para>
  318. Откуда идут данные? Вы можете использовать <varname>$_POST</varname>,
  319. <varname>$_GET</varname>, и любые другие источники данных
  320. (например, запросы веб-сервисов):
  321. </para>
  322. <programlisting language="php"><![CDATA[
  323. if ($form->isValid($_POST)) {
  324. // успех
  325. } else {
  326. // неудача
  327. }
  328. ]]>
  329. </programlisting>
  330. <para>
  331. Вам может прийти в голову идея проверять данные одного элемента или
  332. группы элементов с помощью AJAX-запросов.
  333. Метод <code>isValidPartial()</code> будет проверять на корректность
  334. данные части формы. Его отличие от <code>isValid()</code> состоит в
  335. том, что если в данных формы отсутствует какой-либо ключ, то для
  336. этого элемента не будут производиться проверки на корректность
  337. заполнения:
  338. </para>
  339. <programlisting language="php"><![CDATA[
  340. if ($form->isValidPartial($_POST)) {
  341. // все предоставленные элементы прошли все проверки на корректность
  342. } else {
  343. // один или более элементов не прошли проверку на корректность
  344. }
  345. ]]>
  346. </programlisting>
  347. <para>
  348. Для проверки части формы может также использоваться метод
  349. <code>processAjax()</code>. В отличие от
  350. <code>isValidPartial()</code>, в случае неуспеха он возвращает
  351. строку в формате JSON, содержащую сообщения об ошибках заполнения.
  352. </para>
  353. <para>
  354. Если проверка на корректность заполнения была пройдена успешно,
  355. то вы можете извлечь прошедшие фильтрацию данные:
  356. </para>
  357. <programlisting language="php"><![CDATA[
  358. $values = $form->getValues();
  359. ]]>
  360. </programlisting>
  361. <para>
  362. Для того, чтобы извлечь нефильтрованные данные, используйте:
  363. </para>
  364. <programlisting language="php"><![CDATA[
  365. $unfiltered = $form->getUnfilteredValues();
  366. ]]>
  367. </programlisting>
  368. </sect2>
  369. <sect2 id="zend.form.quickstart.errorstatus">
  370. <title>Получение статуса ошибки</title>
  371. <para>
  372. А что в том случае, если форма не прошла проверку на корректность?
  373. Как правило, вы можете просто вывести ее снова, и сообщения
  374. об ошибках будут отображены, если вы используете
  375. декораторы по умолчанию:
  376. </para>
  377. <programlisting language="php"><![CDATA[
  378. if (!$form->isValid($_POST)) {
  379. echo $form;
  380. // или присвойте ее объекту вида и произведите его рендеринг...
  381. $this->view->form = $form;
  382. return $this->render('form');
  383. }
  384. ]]>
  385. </programlisting>
  386. <para>
  387. Если нужно проанализировать ошибки, то есть два способа их
  388. получения. <code>getErrors()</code> возвращает ассоциативный массив
  389. имен элементов и кодов ошибок (где коды ошибок представлены в виде
  390. массива). <code>getMessages()</code> возвращает ассоциативный массив
  391. имен элементов и сообщений об ошибках (где сообщения об ошибках
  392. представлены в виде ассоциативного массива пар 'код
  393. ошибки'/'сообщение об ошибке'). Если элемент не имеет ошибок, то он
  394. не будет включен в массив.
  395. </para>
  396. </sect2>
  397. <sect2 id="zend.form.quickstart.puttingtogether">
  398. <title>Объединяя изложенное</title>
  399. <para>
  400. Давайте создадим простую форму для входа на сайт. Для нее будут
  401. нужны следующие элементы:
  402. </para>
  403. <itemizedlist>
  404. <listitem><para>username</para></listitem>
  405. <listitem><para>password</para></listitem>
  406. <listitem><para>submit</para></listitem>
  407. </itemizedlist>
  408. <para>
  409. Для примера предположим, что корректное имя пользователя должно
  410. содержать только буквенно-цифровые символы, начинаться с буквы,
  411. иметь длину не меньше 6 и не больше 20 символов, кроме этого, имена
  412. пользователей должны быть приведены к нижнему регистру. Пароль
  413. должен содержать как минимум 6 символов. Переданное значение кнопки
  414. использоваться не будет, поэтому проверка для нее может не
  415. производиться.
  416. </para>
  417. <para>
  418. Мы используем мощь конфигурационных опций <code>Zend_Form</code> для
  419. построения формы:
  420. </para>
  421. <programlisting language="php"><![CDATA[
  422. $form = new Zend_Form();
  423. $form->setAction('/user/login')
  424. ->setMethod('post');
  425. // Создание и конфигурирование элемента username
  426. $username = $form->createElement('text', 'username');
  427. $username->addValidator('alnum')
  428. ->addValidator('regex', false, array('/^[a-z]+/'))
  429. ->addValidator('stringLength', false, array(6, 20))
  430. ->setRequired(true)
  431. ->addFilter('StringToLower');
  432. // Создание и конфигурирование элемента password
  433. $password = $form->createElement('password', 'password');
  434. $password->addValidator('StringLength', false, array(6))
  435. ->setRequired(true);
  436. // Добавление элементов в форму:
  437. $form->addElement($username)
  438. ->addElement($password)
  439. // addElement() используется в качестве "фабрики"
  440. // для создания кнопки 'Login':
  441. ->addElement('submit', 'login', array('label' => 'Login'));
  442. ]]>
  443. </programlisting>
  444. <para>
  445. Затем создается контроллер для отображения формы и ее обработки:
  446. </para>
  447. <programlisting language="php"><![CDATA[
  448. class UserController extends Zend_Controller_Action
  449. {
  450. public function getForm()
  451. {
  452. // здесь должен быть код для создания формы, приведенный выше
  453. return $form;
  454. }
  455. public function indexAction()
  456. {
  457. // рендеринг user/form.phtml
  458. $this->view->form = $this->getForm();
  459. $this->render('form');
  460. }
  461. public function loginAction()
  462. {
  463. if (!$this->getRequest()->isPost()) {
  464. return $this->_forward('index');
  465. }
  466. $form = $this->getForm();
  467. if (!$form->isValid($_POST)) {
  468. // проверка на корректность не пройдена, выводим форму снова
  469. $this->form = $form;
  470. return $this->render('form');
  471. }
  472. $values = $form->getValues();
  473. // аутентификация...
  474. }
  475. }
  476. ]]>
  477. </programlisting>
  478. <para>
  479. ...и скрипт вида для отображения формы:
  480. </para>
  481. <programlisting language="php"><![CDATA[
  482. <h2>Please login:</h2>
  483. <?= $this->form ?>
  484. ]]>
  485. </programlisting>
  486. <para>
  487. Как вы наверное заметили, код контроллера не является полным -
  488. после успешно проведенной проверки должна производиться авторизация
  489. пользователя (например, используя <code>Zend_Auth</code>).
  490. </para>
  491. </sect2>
  492. <sect2 id="zend.form.quickstart.config">
  493. <title>Использование объекта Zend_Config</title>
  494. <para>
  495. Все классы <code>Zend_Form</code> можно конфигурировать, используя
  496. <code>Zend_Config</code>. Вы можете передавать объект
  497. <code>Zend_Config</code> либо конструктору, либо через метод
  498. <code>setConfig()</code>. Посмотрим, как можно создать описанную
  499. выше форму, используя файл INI. Во-первых, будем следовать
  500. рекомендации размещать конфигурации в разделах, отражающих
  501. местонахождение релиза, и сфокусируемся на разделе 'development'.
  502. Во-вторых, установим раздел для данного контроллера ('user') и
  503. ключ для формы ('login'):
  504. </para>
  505. <programlisting language="ini"><![CDATA[
  506. [development]
  507. ; общие метаданные для формы
  508. user.login.action = "/user/login"
  509. user.login.method = "post"
  510. ; элемент username
  511. user.login.elements.username.type = "text"
  512. user.login.elements.username.options.validators.alnum.validator = "alnum"
  513. user.login.elements.username.options.validators.regex.validator = "regex"
  514. user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
  515. user.login.elements.username.options.validators.strlen.validator = "StringLength"
  516. user.login.elements.username.options.validators.strlen.options.min = "6"
  517. user.login.elements.username.options.validators.strlen.options.max = "20"
  518. user.login.elements.username.options.required = true
  519. user.login.elements.username.options.filters.lower.filter = "StringToLower"
  520. ; элемент password
  521. user.login.elements.password.type = "password"
  522. user.login.elements.password.options.validators.strlen.validator = "StringLength"
  523. user.login.elements.password.options.validators.strlen.options.min = "6"
  524. user.login.elements.password.options.required = true
  525. ; элемент кнопки
  526. user.login.elements.submit.type = "submit"
  527. ]]></programlisting>
  528. <para>
  529. Вы можете потом передать это конструктору формы:
  530. </para>
  531. <programlisting language="php"><![CDATA[
  532. $config = new Zend_Config_Ini($configFile, 'development');
  533. $form = new Zend_Form($config->user->login);
  534. ]]></programlisting>
  535. <para>
  536. ... и вся форма будет определена.
  537. </para>
  538. </sect2>
  539. <sect2 id="zend.form.quickstart.conclusion">
  540. <title>Заключение</title>
  541. <para>
  542. Надеемся, что благодаря этому небольшому обучающему руководству вы
  543. смогли получить представление о мощи и гибкости
  544. <code>Zend_Form</code>. Для получения более подробной
  545. информации читайте раздел далее.
  546. </para>
  547. </sect2>
  548. </sect1>
  549. <!--
  550. vim:se ts=4 sw=4 et:
  551. -->