Einführung

Einführung – Was ist der Zweck des Packages

Warum "Controller"?

Das Package implementiert einen PageController-Design-Pattern, was grundsätzlich bedeutet, dass eine einzelne Seite verschiedene Requests und Aktionen verarbeitet abhängig von den Parametern die per GET- oder Post-Request übermittelt wurden. Das Pattern wird ausführlich auf Martin Fowler's Website und der WACT-Projekt-Webseite beschrieben.

Was bedeutet das in Hinblick auf QuickForm: wir haben ein einzelnes Skript, das verschiedene Formulare darstellt und validieren kann, abhängig von den Daten der Parameter des Request. Damit können Sie leicht komplexe Formulare aufbauen, die aus verschiedenen Seiten bestehen, wie z.B. Wizards.

Die typische Implementierung des PageController-Pattern sieht so aus:

<?php
switch ($_REQUEST['action']) {
    case 
'foo':
        
doFoo();
        break;
    case 
'bar':
        
doBar();
        break;
    default:
        echo 
'Hello, world!';
}
?>

HTML_QuickForm_Controller ist komplexer, es gibt drei Basisklassen:

  • HTML_QuickForm_Controller: Diese Klasse extrahiert den Namen der Aktion des Request und ruft den entsprechenden Handler. Es enthält verschiedene Seiten.

  • HTML_QuickForm_Page: Diese Klasse stellt eine einzelne Seite eines Formulars dar, sie erweitert die Klasse HTML_QuickForm.

  • HTML_QuickForm_Action: Diese Klassse implementiert das Command-Design-Patttern, prinzipell ist es ein OO-Callback.

Die durch den Request übermittelte Aktion besteht aus dem Seitennamen und dem Aktionsnamen, es definiert, welche Seite verarbeitet wird (dargestellt bzw. geprüft), und was die Seite genau tun soll.

Einfaches Beispiel

Session-Initialisierung

Dieses Beispiel verwendet keine Sessions, da keine Daten zwischen den Sitenaufrufen gesichert werden müssen. Sessions sind aber erforderlich, wenn real mehrseitige Formulare verwendet werden sollen. HTML_QuickForm_Controller startet nicht automatisch eine Session, die Funktion session_start() muss in solchen Fällen aufgerufen werden, bevor ein entsprechendes Objekt dieser Klasse erzeugt wird.

Um die Funktionen des Packages einfacher zu verstehen, nehmen wir das Bispielformular aus dem HTML_QuickForm tutorial und implementieren es auf Basis von HTML_QuickForm_Controller:

Basis Controller-Benutzung

<?php
// Load the controller
require_once 'HTML/QuickForm/Controller.php';
// Load the base Action class (we will subclass it later)
require_once 'HTML/QuickForm/Action.php';

// Class representing a form
class FirstPage extends HTML_QuickForm_Page
{
    function 
buildForm()
    {
        
$this->_formBuilt true;

        
// Add some elements to the form
        
$this->addElement('header'null'QuickForm tutorial example');
        
$this->addElement('text''name''Enter your name:', array('size' => 50'maxlength' => 255));
        
// Note how we set the name of the submit button
        
$this->addElement('submit'$this->getButtonName('submit'), 'Send');

        
// Define filters and validation rules
        
$this->applyFilter('name''trim');
        
$this->addRule('name''Please enter your name''required'null'client');

        
$this->setDefaultAction('submit');
    }
}

// Action to process the form
class ActionProcess extends HTML_QuickForm_Action
{
    function 
perform(&$page$actionName)
    {
        echo 
'<h1>Hello, ' htmlspecialchars($page->exportValue('name')) . '!</h1>';
    }
}

$page =& new FirstPage('firstForm');

// We only add the 'process' handler, Controller will care for default ones
$page->addAction('process', new ActionProcess());

// Instantiate the Controller
$controller =& new HTML_QuickForm_Controller('tutorial');

// Set defaults for the form elements
$controller->setDefaults(array(
    
'name' => 'Joe User'
));

// Add the page to Controller
$controller->addPage($page);

// Process the request
$controller->run();
?>

Es fällt auf, das der Code wesentlich umfangreicher ist, als das Original. Tatsächlich müssen wir nur drei Klassen von HTML_QuickForm_Page ableiten, um einen dreiseitigen Wizard zu erzeugen, den 'process'-Eventhandler basierend auf HTML_QuickForm_Action implementieren und zum Controller hinzufügen. Ohne den Controller wäre der Programmieraufwand bedeutend höher.

Angepasste Seiten erzeugen

Sie müssen HTML_QuickForm_Page ableiten und die Methode buildForm() überschreiben. Der Inhalt ist weitgehend selbsterklärend, wenn Sie mit QuickForm vertraut sind, mit Ausnahme einiger Kleinigkeiten:

<?php
$this
->_formBuilt true;
?>

Die Formularerzeugung ist eine aufwendige Operation, so dass die buildForm()-Methode nur dann aufgerufen wird, wenn es notwendig ist. Um zu verhindern, dass sie zweimal aufgerufen wird (und damit zwei Elementsätze erzeugt werden, statt einem), setzen wir die Variable $_formBuilt-Eigenschaft.

Die zweite interessante Zeile ist

<?php
$this
->addElement('submit'$this->getButtonName('submit'), 'Send');
?>

Wir benutzen die Methode getButtonName() um den Namen des Submit-Buttons zu setzen und die 'submit'-Aktion auszulösen, wenn der Butten geklickt wird.

Die dritte Sache ist

<?php
$this
->setDefaultAction('submit');
?>

Der Benutzer kann das Formular über den Enter-Button abschicken, nicht durch Klick auf einen anderen Formular-Button. Die meisten Browser würden in diesem Fall den Submit-Button nicht als geklickt interpretieren und nicht dessen Namen übertragen. setDefaultAction() setzt die Aktion durch Hinzufügen eines versteckten Elementes im Formular, die dann aufgerufen wird.

Eigene Aktionen erzeugen

Normalerweise müssen Sie Handler für zwei Aktionen implementieren: 'process' und 'display'. Über das Erste kann hier keine Aussage gemacht werden, schließlich ist die Verarbeitung applikationsspezifisch. Für zweite Aktion leiten sie eine Klasse von HTML_QuickForm_Action_Display ab und überschreiben dessen _renderForm()-Methode, um den entsprechenden Renderer aufzurufen und dir Formularausgabe anzupassen.

Zusammenführen

Als nächstes erzeugen wir ein Objekt unser obigen Page-Klasse.

<?php
$page 
=& new FirstPage('firstForm');
?>

und ergänzen unsere eigenen Aktions-Handler:

<?php
$page
->addAction('process', new ActionProcess());
?>

Die 'process'-Aktion wird standardmäßig von der 'submit'-Aktion aufgerufen, wenn das Formular gültig ist.

Jetzt holen wir ein neues Controller-Objekt:

<?php
$controller 
=& new HTML_QuickForm_Controller('tutorial');
?>

Der Name ist ein erforderlicher Parameter, und wenn Sie verschiedene Controller in ihrer Anwendung haben, sollten sie verschiedene Namen besitzen, da sie unter diesem Namen in der Session gespeichert werden.

Weiter setzen wir die Standardwerte für das Formular und fügen die Seite hinzu.

<?php
$controller
->setDefaults(array(
    
'name' => 'Joe User'
));
$controller->addPage($page);
?>

Es ist zulässig, die setDefaults()-Methode innerhalb von buildForm() aufzurufen, aber der gezeigt Weg zum Setzen der Standardwerte setzt Sie alle gesamt, während der letztere nur die Werte für die aktuelle Seite setzt.

Zum Schluß rufen wir die Controller-Methode run() auf:

<?php
$controller
->run();
?>

Sie kümmert sich darum, den Namen der aktuellen Aktion zu finden und ruft den erforderlichen Handler auf.

Fortgeschrittene Beispiele

... befinden Sie im Package-Archiv. Zusätzlich zum bereits gezeigten Beispiel, existieren zwei Beispiel für mehrseitige Formulare:

  • Wizard: Formularseiten enthalten 'Next'- und 'Back'-Buttons und es kann nicht zur nächsten Seite nicht gewechselt werden, solange die jeweilige Seite nicht korrekt ausgefüllt wurde.

  • Karteireiter-Dialoge ("Tabbed form"): Formular das aus verschiedenen Seiten besteht und Buttons besitzen, um direkt auf eine bestimmte Seite zu springen. Das Formular ist erst dann gültig, wenn der überall verfügbare 'Submit'-Button gedrückt wurde.

HTML_QuickForm_Controller (Previous) Understanding package features (Next)
Last updated: Sun, 19 Dec 2010 — Download Documentation
Do you think that something on this page is wrong? Please file a bug report or add a note.
View this page in:

User Notes:

Note by: Ed Greenberg
Look in the doc directory under pear...

pear/doc/HTML_QuickForm_Controller/examples/wizard.php

and others
Note by: powtac@gmx.de
Couldn't there be a example with 2 or more quickform pages?