| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.form.quickstart">
- <title>Schnellstart mit Zend_Form</title>
- <para>
- Diese Anleitung soll die Grundsätze der Erstellung, Validierung und
- Darstellung von Formularen mit <classname>Zend_Form</classname> zeigen.
- </para>
- <sect2 id="zend.form.quickstart.create">
- <title>Ein Form Objekt erstellen</title>
- <para>
- Die Erstellung eines Formular Objektes ist sehr einfach: nur
- <classname>Zend_Form</classname> instanzieren:
- </para>
- <programlisting language="php"><![CDATA[
- $form = new Zend_Form;
- ]]></programlisting>
- <para>
- Für fortgeschrittene Anwendungsfälle, kann man eine <classname>Zend_Form</classname>
- Unterklasse erstellen, aber für einfache Formulare, kann ein Formular programmtechnisch
- mit einem <classname>Zend_Form</classname> erstellt werden.
- </para>
- <para>
- Wenn man bei einem Formular Aktion und Methode spezifizieren will (immer eine gute
- Idee), kann das mit den <methodname>setAction()</methodname> und
- <methodname>setMethod()</methodname> Methoden gemacht werden:
- </para>
- <programlisting language="php"><![CDATA[
- $form->setAction('/resource/process')
- ->setMethod('post');
- ]]></programlisting>
- <para>
- Der obige Code setzt die Formular Aktion zu der partiellen <acronym>URL</acronym>
- "<filename>/resource/process</filename>" und die Formular Methode zu
- <acronym>HTTP</acronym> <acronym>POST</acronym>. Das wird
- während der endgültigen Darstellung berücksichtigt.
- </para>
- <para>
- Man kann zusätzliche <acronym>HTML</acronym> Attribute für das
- <emphasis><form></emphasis> Tag setzen, indem die
- <methodname>setAttrib()</methodname> oder <methodname>setAttribs()</methodname> Methoden
- verwendet werden. Zum Beispiel wenn man die ID setzen will, setzt man das
- "<property>id</property>" Attribut:
- </para>
- <programlisting language="php"><![CDATA[
- $form->setAttrib('id', 'login');
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.elements">
- <title>Elemente einer Form hinzufügen</title>
- <para>
- Ein Formular ist nichts ohne seine Elemente. <classname>Zend_Form</classname> kommt mit
- einigen Standardelementen die <acronym>XHTML</acronym> über
- <classname>Zend_View</classname> Helfer darstellen. Das sind die folgenden:
- </para>
- <itemizedlist>
- <listitem><para>button</para></listitem>
- <listitem>
- <para>checkbox (oder viele Checkboxen auf einmal mit multiCheckbox)</para>
- </listitem>
- <listitem><para>hidden</para></listitem>
- <listitem><para>image</para></listitem>
- <listitem><para>password</para></listitem>
- <listitem><para>radio</para></listitem>
- <listitem><para>reset</para></listitem>
- <listitem><para>select (beide, normale und Mehrfachauswahl Typen)</para></listitem>
- <listitem><para>submit</para></listitem>
- <listitem><para>text</para></listitem>
- <listitem><para>textarea</para></listitem>
- </itemizedlist>
- <para>
- Es gibt zwei Optionen für das Hinzufügen von Elementen zu einem Formular: Man kann ein
- konkretes Element instanzieren und dieses dem Objekt übergeben, oder man kann den Typ
- des Elements übergeben und <classname>Zend_Form</classname> ein Objekt des richtigen
- Typs für einen instanzieren lassen.
- </para>
- <para>
- Einige Beispiele:
- </para>
- <programlisting language="php"><![CDATA[
- // Ein Element instanzieren und an das Form Objekt übergeben:
- $form->addElement(new Zend_Form_Element_Text('username'));
- // Den Fyp des Form Elements dem Form Objekt übergeben:
- $form->addElement('text', 'username');
- ]]></programlisting>
- <para>
- Standardmäßig haben diese Elemente keine Prüfer oder Filter. Das bedeutet, dass man
- eigene Elemente mit minimalen Prüfern und potentiellen Filtern konfigurieren muss. Man
- kann das entweder (a) vor der Übergabe des Elements an das Formular machen, (b) über
- Konfigurationsoptionen die bei der Erstellung des Elements über
- <classname>Zend_Form</classname> angegeben werden, oder (c), durch beziehen des Elements
- vom Formular Objekt und dessen Konfiguration im nachhinein.
- </para>
- <para>
- Betrachten wir zuerst die Erstellung eines Prüfers für eine konkrete Instanz eines
- Elements. Es können entweder <classname>Zend_Validate_*</classname> Instanzen übergeben
- werden, oder der Name des Prüfers, der verwendet werden soll:
- </para>
- <programlisting language="php"><![CDATA[
- $username = new Zend_Form_Element_Text('username');
- // Ein Zend_Validate_* Objekt übergeben:
- $username->addValidator(new Zend_Validate_Alnum());
- // Den Namen des Prüfers übergeben:
- $username->addValidator('alnum');
- ]]></programlisting>
- <para>
- Wenn die zweite Option verwendet wird, kann, wenn der Prüfer Argumente im Konstruktor
- akzeptiert, diesem ein Array als dritter Parameter übergeben werden:
- </para>
- <programlisting language="php"><![CDATA[
- // Ein Pattern übergeben
- $username->addValidator('regex', false, array('/^[a-z]/i'));
- ]]></programlisting>
- <para>
- (Der zweite Parameter wird verwendet um anzuzeigen, ob spätere Prüfer bei einem Fehler
- dieses Prüfers ausgeführt werden sollen oder nicht; standardmäßig ist er
- <constant>FALSE</constant>.)
- </para>
- <para>
- Es kann auch gewünscht sein, ein Element als benötigt zu spezifizieren. Das kann durch
- Verwendung eines Accessors getan werden, oder durch die Übergabe einer Option bei der
- Erstellung des Elements. Im ersteren Fall:
- </para>
- <programlisting language="php"><![CDATA[
- // Dieses Element als benötigt definieren:
- $username->setRequired(true);
- ]]></programlisting>
- <para>
- Wenn ein Element benötigt wird, wird ein 'NotEmpty' Prüfer ganz oben in der Prüfkette
- definiert, um sicherzustellen, dass dieses Element einen Wert hat wenn er benötigt wird.
- </para>
- <para>
- Filter werden grundsätzlich auf dem gleichen Weg, wie die Prüfer, definiert. Zu
- Anschauungszwecken, wird ein Filter hinzugefügt, der den endgültigen Wert
- klein schreibt:
- </para>
- <programlisting language="php"><![CDATA[
- $username->addFilter('StringtoLower');
- ]]></programlisting>
- <para>
- Das endgültige Setup, des Elements, könnte wie folgt aussehen:
- </para>
- <programlisting language="php"><![CDATA[
- $username->addValidator('alnum')
- ->addValidator('regex', false, array('/^[a-z]/'))
- ->setRequired(true)
- ->addFilter('StringToLower');
- // oder kompakter:
- $username->addValidators(array('alnum',
- array('regex', false, '/^[a-z]/i')
- ))
- ->setRequired(true)
- ->addFilters(array('StringToLower'));
- ]]></programlisting>
- <para>
- So einfach das ist, ist das für jedes einzelne Elemet in einer Form sehr aufwendig.
- Versuchen wir es also mit Option (b) von oben. Wenn wir ein neues Element erstellen
- wird <methodname>Zend_Form::addElement()</methodname> als Factory verwendet, und wir
- können optional Konfigurationsoptionen übergeben. Diese können Prüfer und Filter
- enthalten die angepasst werden können. Um alles von oben implizit durchzuführen,
- versuchen wir folgendes:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addElement('text', 'username', array(
- 'validators' => array(
- 'alnum',
- array('regex', false, '/^[a-z]/i')
- ),
- 'required' => true,
- 'filters' => array('StringToLower'),
- ));
- ]]></programlisting>
- <note>
- <para>
- Wenn man sieht, dass man Elemente welche die gleichen Optionen in vielen Plätzen
- verwenden, konfiguriert, kann es gewünscht sein, eine eigene
- <classname>Zend_Form_Element</classname> Unterklasse zu erstellen und diese
- stattdessen anzupassen; das spart viel Tipparbeit im weiteren Verlauf.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.form.quickstart.render">
- <title>Ein Formular darstellen</title>
- <para>
- Die Darstellung eines Formulars ist einfach. Die meisten Elemente verwenden einen
- <classname>Zend_View</classname> Helfer, um sich selbst darzustellen und benötigen
- deshalb ein View Objekt, um dargestellt zu werden. Dafür gibt es zwei unterschiedliche
- Varianten: Die <code>render()</code> Methode des Formulare verwenden, oder ein einfaches
- <code>echo</code>.
- </para>
- <programlisting language="php"><![CDATA[
- // Explizit render() aufrufen und ein optionales View Objekt übergeben:
- echo $form->render($view);
- // Angenommen ein View Objekt wurde vorher über setView() gesetzt:
- echo $form;
- ]]></programlisting>
- <para>
- Standardmäßig versuchen <classname>Zend_Form</classname> und
- <classname>Zend_Form_Element</classname> ein im <classname>ViewRenderer</classname>
- initialisiertes View Objekt zu verwenden, was bedeutet, dass die View nicht manuell
- gesetzt werden muss, wenn das <acronym>MVC</acronym> des Zend Frameworks verwendet wird.
- Die Darstellung eines Formulars in einem View Skript ist sehr einfach:
- </para>
- <programlisting language="php"><![CDATA[
- <?php $this->form ?>
- ]]></programlisting>
- <para>
- Unter der Hand verwendet <classname>Zend_Form</classname> "Dekoratoren" um die
- Darstellung durchzuführen. Diese Dekoratoren können Inhalte ersetzen, anfügen oder
- voranstellen, und haben eine volle Introspektive des Elements das Ihnen übergeben wurde.
- Als Ergebnis können mehrere Dekoratoren kombiniert werden, um eigene Effekte zu
- ermöglichen. Standardmüßig kombiniert <classname>Zend_Form_Element</classname> View
- Dekoratoren um seine Ausgaben zu erstellen; das Setup sieht ähnlich diesem aus:
- </para>
- <programlisting language="php"><![CDATA[
- $element->addDecorators(array(
- 'ViewHelper',
- 'Errors',
- array('HtmlTag', array('tag' => 'dd')),
- array('Label', array('tag' => 'dt')),
- ));
- ]]></programlisting>
- <!-- TODO: Wozu gehört dieser Paragraph? Ich sehe nirgends "HELPERNAME". -->
- <para>
- (Wobei <HELPERNAME> der Name des View Helfers ist der verwendet wird, und
- variiert basierend auf dem Element.)
- </para>
- <para>
- Das obige Beispiel erstellt eine Ausgabe, ähnlich der folgenden:
- </para>
- <programlisting language="html"><![CDATA[
- <dt><label for="username" class="required">Username</dt>
- <dd>
- <input type="text" name="username" value="123-abc" />
- <ul class="errors">
- <li>'123-abc' has not only alphabetic and digit characters</li>
- <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
- </ul>
- </dd>
- ]]></programlisting>
- <para>
- (Wenngleich nicht mit der gleichen Formatierung.)
- </para>
- <para>
- Die Dekoratoren die von einem Element verwendet werden, können geändert werden, um eine
- andere Ausgabe zu erzeugen; seihe dazu das
- <link linkend="zend.form.decorators">Kapitel über Dekoratoren</link> für mehr
- Informationen.
- </para>
- <para>
- Das Formular selbst, geht alle Elemente durch, und fügt diese in eine
- <acronym>HTML</acronym> <emphasis><form></emphasis> ein. Die Aktion und Methode,
- die bei der Erstellung des Formulars angegeben wurden, werden dem
- <emphasis><form></emphasis> Tag angegeben, wie wenn sie Attribute wären, die über
- <methodname>setAttribs()</methodname> und ähnliche gesetzt werden.
- </para>
- <para>
- Elemente werden, entweder in der Reihenfolge in der sie registriert wurden durchlaufen,
- oder, wenn ein Element ein 'order' Attribut enthält, in dieser Reihenfolge. Die
- Reihenfolge eines Elements kann, wie folgt, gesetzt werden:
- </para>
- <programlisting language="php"><![CDATA[
- $element->setOrder(10);
- ]]></programlisting>
- <para>
- Oder bei der Erstellung des Elements durch Übergabe als Option:
- </para>
- <programlisting language="php"><![CDATA[
- $form->addElement('text', 'username', array('order' => 10));
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.validate">
- <title>Prüfen, ob ein Formular gültig ist</title>
- <para>
- Nachdem ein Formular übermittelt wurde, muss diese geprüft werden, um zu sehen ob sie
- alle Prüfungen besteht. Jedes Element wird gegen die angegebenen Daten geprüft; wenn ein
- Schlüssel, der dem Elementnamen entspricht, nicht vorhanden ist, und das Element als
- benötigt markiert ist, werden die Prüfungen mit einem <constant>NULL</constant> Wert
- ausgeführt.
- </para>
- <para>
- Wo kommen die Daten her? Man kann <varname>$_POST</varname> oder
- <varname>$_GET</varname> verwenden, oder jede andere Datenquelle die man bei der Hand
- hat (Web Service Anfragen zum Beispiel):
- </para>
- <programlisting language="php"><![CDATA[
- if ($form->isValid($_POST)) {
- // erfolgreich!
- } else {
- // fehlgeschlagen!
- }
- ]]></programlisting>
- <para>
- Mit <acronym>AJAX</acronym> Anfragen kann man manchmal davon abweichen einzelne Elemente
- oder Gruppen von Elementen zu prüfen. <methodname>isValidPartial()</methodname> prüft
- einen Teil des Formulars. Anders, als <methodname>isValid()</methodname>, werden, wenn
- ein spezieller Schlüssel nicht vorhanden ist, Prüfungen für dieses spezielle Element
- nicht durchgeführt:
- </para>
- <programlisting language="php"><![CDATA[
- if ($form->isValidPartial($_POST)) {
- // Elemente hat alle Prüfungen bestanden
- } else {
- // Ein oder mehrere getestete Elemente haben die Prüfung nicht bestanden
- }
- ]]></programlisting>
- <para>
- Eine zusätzliche Methode, <methodname>processAjax()</methodname>, kann auch dafür
- verwendet werden, um Teilformen zu prüfen. Anders als
- <methodname>isValidPartial()</methodname>, gibt sie eine <acronym>JSON</acronym>
- formatierten Zeichenkette zurück, die bei einem Fehler, die Fehlermeldungen enthält.
- </para>
- <para>
- Angenommen die Prüfungen sind durchgeführt worden, dann können jetzt die gefilterten
- Werte geholt werden:
- </para>
- <programlisting language="php"><![CDATA[
- $values = $form->getValues();
- ]]></programlisting>
- <para>
- Wenn an irgendeinem Punkt die ungefilterten Werte benötigt werden, kann man folgendes
- verwenden:
- </para>
- <programlisting language="php"><![CDATA[
- $unfiltered = $form->getUnfilteredValues();
- ]]></programlisting>
- <para>
- Wenn man andererseits alle gültigen und gefilterten Werte eines teilweise gültigen
- Formulars benötigt kann folgendes aufgerufen werden:
- </para>
- <programlisting language="php"><![CDATA[
- $values = $form->getValidValues($_POST);
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.form.quickstart.errorstatus">
- <title>Fehlerstatus holen</title>
- <para>
- Das Formular hat die Prüfungen nicht bestanden? In den meisten Fällen, kann das Formular
- neu dargestellt werden, und Fehler werden angezeigt wenn Standardekoratoren verwendet
- werden:
- </para>
- <programlisting language="php"><![CDATA[
- if (!$form->isValid($_POST)) {
- echo $form;
- // oder dem View Obejekt zuordnen und eine View darstellen...
- $this->view->form = $form;
- return $this->render('form');
- }
- ]]></programlisting>
- <para>
- Wenn die Fehler inspiziert werden sollen, gibt es zwei Methoden.
- <methodname>getErrors()</methodname> gibt ein assoziatives Array von Elementnamen/Codes
- zurück (wobei Codes ein Array von Fehlercodes ist).
- <methodname>getMessages()</methodname> gibt ein assoziatives Array von
- Elementnamen/Nachrichten zurück (wobei Nachrichten ein assoziatives Array von
- Fehlercodes/Fehlernachrichten Paaren ist). Wenn ein gegebenes Element keinen Fehler
- hat, wird es dem Array nicht angefügt.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.puttingtogether">
- <title>Alles zusammenfügen</title>
- <para>
- Bauen wir also ein Login Formular. Es benötigt Elemente die folgendes repräsentieren:
- </para>
- <itemizedlist>
- <listitem><para>username</para></listitem>
- <listitem><para>password</para></listitem>
- <listitem><para>submit</para></listitem>
- </itemizedlist>
- <para>
- Für unsere Zwecke nehmen wir an, dass ein gültiger Benutzername nur alphanumerische
- Zeichen enthalten soll und mit einem Buchstaben beginnt, eine Mindestlänge von 6 und
- eine Maximallänge von 20 Zeichen hat; er wird zu Kleinschreibung normalisiert.
- Passwörter müssen mindestens 6 Zeichen lang sein. Der submit Wert wird einfach ignoriert
- wenn wir fertig sind, er kann also ungeprüft bleiben.
- </para>
- <para>
- Wir verwenden die Stärke von <classname>Zend_Form</classname>'s Konfigurationsoptionen
- um die Form zu erstellen:
- </para>
- <programlisting language="php"><![CDATA[
- $form = new Zend_Form();
- $form->setAction('/user/login')
- ->setMethod('post');
- // Ein username Element erstellen und konfigurieren:
- $username = $form->createElement('text', 'username');
- $username->addValidator('alnum')
- ->addValidator('regex', false, array('/^[a-z]+/'))
- ->addValidator('stringLength', false, array(6, 20))
- ->setRequired(true)
- ->addFilter('StringToLower');
- // Ein Passwort Element erstellen und konfigurieren:
- $password = $form->createElement('password', 'password');
- $password->addValidator('StringLength', false, array(6))
- ->setRequired(true);
- // Elemente dem Formular hinzufügen:
- $form->addElement($username)
- ->addElement($password)
- // addElement() als Factory verwenden um den 'Login' Button zu erstellen:
- ->addElement('submit', 'login', array('label' => 'Login'));
- ]]></programlisting>
- <para>
- Als nächstes wird ein Controller erstellt der das Formular behandelt:
- </para>
- <programlisting language="php"><![CDATA[
- class UserController extends Zend_Controller_Action
- {
- public function getForm()
- {
- // Formular, wie oben beschrieben, erstellen
- return $form;
- }
- public function indexAction()
- {
- // user/form.phtml darstellen
- $this->view->form = $this->getForm();
- $this->render('form');
- }
- public function loginAction()
- {
- if (!$this->getRequest()->isPost()) {
- return $this->_forward('index');
- }
- $form = $this->getForm();
- if (!$form->isValid($_POST)) {
- // Fehlgeschlagene Prüfung; Form wieder anzeigen
- $this->view->form = $form;
- return $this->render('form');
- }
- $values = $form->getValues();
- // Jetzt versuchen zu Authentifizieren...
- }
- }
- ]]></programlisting>
- <para>
- Und ein View Skript für die Darstellung des Formulars:
- </para>
- <programlisting language="php"><![CDATA[
- <h2>Bitte anmelden:</h2>
- <?php echo $this->form ?>
- ]]></programlisting>
- <para>
- Wie man im Controller Code sieht, gibt es mehr Arbeit zu tun: Während die Übertragung
- gültig sein muss, kann es trotzdem notwendig sein, zum Beispiel, ein Authentifizierung
- mit Hilfe von <classname>Zend_Auth</classname> durchzuführen.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.config">
- <title>Ein Zend_Config Objekt verwenden</title>
- <para>
- Alle <classname>Zend_Form</classname>'s sind konfigurierbar, indem
- <classname>Zend_Config</classname> verwendet wird; es kann entweder ein
- <classname>Zend_Config</classname> Objekt an den Kontruktor oder über
- <methodname>setConfig()</methodname> übergeben werden. Sehen wir uns an, wie das obige
- Formular erstellt werden kann, wenn wir eine <acronym>INI</acronym> Datei verwenden.
- Zuerst folgen wir den Notwendigkeiten und platzieren die Konfigurationen in Sektionen,
- die den Ort des Releases reflektieren, und fokusieren auf die 'development' Sektion. Als
- nächstes wird eine Sektion für den gegebenen Controller ('user') definiert und ein
- Schlüssel für das Formular ('login'):
- </para>
- <programlisting language="ini"><![CDATA[
- [development]
- ; general form metainformation
- user.login.action = "/user/login"
- user.login.method = "post"
- ; username element
- user.login.elements.username.type = "text"
- user.login.elements.username.options.validators.alnum.validator = "alnum"
- user.login.elements.username.options.validators.regex.validator = "regex"
- user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
- user.login.elements.username.options.validators.strlen.validator = "StringLength"
- user.login.elements.username.options.validators.strlen.options.min = "6"
- user.login.elements.username.options.validators.strlen.options.max = "20"
- user.login.elements.username.options.required = true
- user.login.elements.username.options.filters.lower.filter = "StringToLower"
- ; password element
- user.login.elements.password.type = "password"
- user.login.elements.password.options.validators.strlen.validator = "StringLength"
- user.login.elements.password.options.validators.strlen.options.min = "6"
- user.login.elements.password.options.required = true
- ; submit element
- user.login.elements.submit.type = "submit"
- ]]></programlisting>
- <para>
- Das kann dann an den Contruktor des Formulars übergeben werden:
- </para>
- <programlisting language="php"><![CDATA[
- $config = new Zend_Config_Ini($configFile, 'development');
- $form = new Zend_Form($config->user->login);
- ]]></programlisting>
- <para>
- und das komplette Formular wird definiert werden.
- </para>
- </sect2>
- <sect2 id="zend.form.quickstart.conclusion">
- <title>Schlussfolgerung</title>
- <para>
- Hoffentlich ist, mit dieser kleinen Anleitung der Weg klar, um die Leistung und
- Flexibilität von <classname>Zend_Form</classname> einzusetzen. Für detailiertere
- Informationen lesen Sie weiter!
- </para>
- </sect2>
- </sect1>
|