Zend Framework Quickstart

Aus Zend Framework Wiki

Wechseln zu: Navigation, Suche

Dieser Schnellstart (engl. Quickstart) soll den Einstieg in die Programmierung einer Webanwendung mit dem Zend Framework erleichtern. Er basiert auf dem offiziellen englischen Quickstart.

Inhaltsverzeichnis

[Bearbeiten] Einführung in das Zend Framework

Das Zend Framework ist ein quelloffenes, objektorientiertes PHP 5 Framework für Webanwendungen. Es wird oft auch "Komponentenbibliothek" genannt, da es viele lose verbundene Komponenten enthält, die mehr oder weniger unabhängig voneinander verwendet werden können. Aber das Zend Framework bietet auch eine fortschrittliche Model-View-Controller (MVC) Implementation, die dazu verwendet werden kann, eine Basistruktur für Zend Framework Anwendungen aufzubauen. Eine vollständige Liste aller Zend Framework Komponenten zusammen mit kurzen Beschreibungen bietet die Komponentenübersicht. Dieser Schnellstart zeigt einige der am meisten verwendeten Komponenten des Zend Frameworks, inklusive Zend_Controller, Zend_Layout, Zend_Config, Zend_Db, Zend_Db_Table, Zend_Registry und einigen View Helfern. Unter der Verwendung dieser Komponenten werden wir eine datenbankbasierte Gästebuchanwendung erstellen.

[Bearbeiten] Das Model-View-Controller Konzept

Das MVC Konzept

Was ist nun eigentlich dieses MVC Konzept, über das so viele reden und warum sollte es uns interessieren? MVC ist mehr als nur ein drei-buchstabiges Akronym, dass man immer dann erwähnen kann, wann man besonders intelligent klingen will. Es ist so etwas wie ein Standard für das Erstellen moderner Webanwendungen geworden. Und das aus gutem Grund. Der meiste Code einer Webanwendung kann in eine von drei Kategorien eingeordnet werden: Präsentation, Business Logik und Datenzugriff. Das MVC Konzept spiegelt diese Trennung sehr gut wider. Das Endergebnis ist, dass der Präsentationscode in einem Teil der Anwendung, die Business Logik in einem anderen und der Datenzugriff wiederum in einem anderen zusammengefasst werden kann. Viele Entwickler empfinden diese wohl definierte Trennung als unentbehrlich, um ihren Code organisiert zu halten, insbesondere wenn mehr als nur ein Entwickler an der gleichen Anwendung arbeitet.

Schauen wir uns die drei Teile des MVC Konzeptes etwas genauer an:

  • Das Model ist der Teil der Anwendung, dass seine Grundfunktionen durch ein Set von Abstraktionen definiert. Es kann Routinen des Datenzugriffs und Business Logik enthalten.
  • Das View ist der Teil der Anwendung, der bestimmt, was dem Benutzer präsentiert wird. Üblicherweise übergeben Controller einem View Daten, damit sie in irgendeiner Art und Weise vom View darstellt werden. Oft sammelt das View auch Daten vom Benutzer. Im View befindet sich normalerweise auch das HTML Markup der MVC Anwendung.
  • Der Controller verbindet das ganze Konzept. Er manipuliert das Model, entscheidet welches View auf Grundlage einer Benutzeranfrage und weiteren Faktoren dargestellt werden soll, übergibt die Daten an das View oder übergibt die Kontrolle einem anderen Controller. Die meisten MVC Experten empfehlen einen Controller so schlank wie möglich zu halten.

.

[Bearbeiten] Das Zend Framework installieren

Eine Zend Framework basierte Webanwendung entwickelt man häufig auf einem XAMP-System. XAMP ist ein Akronym für den kombinierten Einsatz von einem Betriebssystem, Apache, MySQL und PHP. Es dient dazu dynamische Webseiten darstellen und testen zu können. Man ist aber nicht auf die Verwendung des Apache Webservers und MySQL Datenbankservers festgelegt. Wichtig ist nur, dass der Webserver PHP interpretieren kann.

Zur Installation verschiedener XAMP-Systeme: Zend Server, ...

Ist das XAMP-System eingerichtet, kann das Zend Framework installiert werden. Was gilt es dabei zu beachten? Es ist wichtig zu verstehen, dass das Zend Framework seine einzelnen Klassen selbständig laden kann. Aber auch wenn sie händig geladen werden, sie müssen in beiden Fällen auf der Festplatte gefunden werden können. PHP sucht Dateien ausschließlich im include_path. Dieser enthält beliebig viele Pfade unter denen eine angegebene Datei gesucht wird. Um also das Zend Framework zu installieren, finden wir zuerst heraus, welche Pfade im include_path stehen. Dazu erstellen wir ein kleines PHP Skript, dass den include_path anzeigt. Wir erstellen die Datei includepath.php mit folgendem Inhalt und speichern sie im Webroot-Verzeichnis unseres Webservers:

<?php echo get_include_path(); ?>

Dann rufen wir das Skript mittels http://localhost/includepath.php im Browser auf. Die Ausgabe könnte z. B. so aussehen:

.:/usr/share/php:/usr/share/pear

Das heißt dass drei Pfade im include_path stehen:

  1. . (das jeweils aktuelle Verzeichnis)
  2. /usr/share/php und
  3. /usr/share/pear

In eines der beiden letzteren Verzeichnisse installieren wir das Zend Framework. Wir laden es von http://framework.zend.com herunter und entpacken das Archiv. Den darin enthaltenen Ordner library/Zend kopieren wir in z. B. /usr/share/php.

Nun installieren wir noch das CLI Tool des Zend Frameworks, das bei der Erstellung einer Webanwendung sehr nützlich ist und viel Arbeit abnimmt. Dazu kopieren wir die zwei Dateien bin/zf.php und bin/zf.bat (für Windows) bzw. bin/zf.php und bin/zf.sh (für unixartige Systeme) in den gleichen Ordner wie das Zend Framework. Die Ordnerstruktur sieht dann wie folgt aus:

/usr/share/php/zf.sh
/usr/share/php/zf.php
/usr/share/php/Zend
/usr/share/php/Zend/Version.php (Beispiel eines vollständigen Dateipfades)

Damit das CLI Tool mit dem Befehl zf ausgeführt werden kann, nehmen wir noch folgende Einstellungen vor:

Für unixartige Systeme erstellen wir einen symbolischen Link:

ln -s /usr/share/php/zf.sh /usr/bin/zf

Windows:

//

Um zu testen, ob das Zend Framework und das CLI Tool richtig installiert wurden, lassen wir uns die Version ausgeben:

zf show version

Ausgabe:

Zend Framework Version: 1.10.8

[Bearbeiten] Ein Projekt erstellen

Um unser Projekt zu erstellen, nutzen wir das CLI Tool des Zend Frameworks. Wir öffnen dazu ein Terminal, navigieren in das Verzeichnis in dem wir unser Projekt erstellen wollen und geben folgenden Befehl ein:

zf create project quickstart

Dieser Kommandozeilenbefehl erstellt folgendes Grundstruktur:

quickstart
|-- .zfproject.xml
|-- application
|   |-- Bootstrap.php
|   |-- configs
|   |   `-- application.ini 
|   |-- controllers
|   |   |-- ErrorController.php
|   |   `-- IndexController.php
|   |-- models
|   `-- views
|       |-- helpers
|       `-- scripts
|           |-- error
|           |   `-- error.phtml
|           `-- index
|               `-- index.phtml
|-- docs
|   `-- README.txt
|-- library
|-- public
|   |-- index.php
|   `-- .htaccess
`-- tests
    |-- application
    |   `-- bootstrap.php
    |-- library
    |   `-- bootstrap.php
    `-- phpunit.xml

Da wir im weiteren Verlauf dieses Schnellstarts das CLI Tool noch einmal benutzen werden, lassen wir das Terminal geöffnet und wechseln in unser Projektverzeichnis:

cd quickstart

[Bearbeiten] Ein Projekt konfigurieren

Wärend das Zend Framework selbst konfigurationslos ist, ist es oft notwendig die eigene Anwendung zu konfigurieren. Die Standardkonfiguration wird in application/configs/application.ini platziert und enthält einige grundsätzliche Direktiven für die Einstellung der PHP Umgebung (Application Environment). Durch ein Anpassen des Application Environment kann z. B. die Anzeige von Fehlermeldungen leicht ein- oder ausgeschaltet werden.

Die Datei application/configs/application.ini, wie sie das CLI Tool erstellt, sollte nur erweitert oder angepasst werden. Die Konfiguration ist INI-artig und es kann direkt auf Konstanten referenziert werden. APPLICATION_PATH ist z. B. solch eine Konstante. Zusätzlich ist zu beachten, dass es verschiedene definierte Sektionen gibt: production, staging, testing, und development. Die letzten drei verweisen auf Einstellungen der production Umgebung, d. h. sie erben ihre Konfiguration, sofern sie sie nicht überschreiben. Das ist ein nützlicher Weg um die Konfiguration zu organisieren und stellt sicher, dass die richtigen Einstellungen in jeder Stufe der Anwendungsentwicklung vorhanden sind.

[Bearbeiten] Das Application Environment definieren

Um während des Entwicklungsprozesses unserer Anwendung alle Fehler und Warnungen angezeigt zu bekommen, müssen wir das Application Environment auf development setzen. Wir öffnen dazu die Datei public/.htaccess mit einem Editor und fügen an erste Stelle folgende Zeile hinzu:

SetEnv APPLICATION_ENV development

[Bearbeiten] Einen vHost erstellen

Angenommen, wir haben unser Projekt unterhalb des Webroots angelegt, dann lautet die URL der Startseite unserer Webanwendung http://localhost/quickstart/public/. Aus Sicherheitsgründen sollte aber das Wurzelverzeichnis der URL der public Ordner unseres Projekts sein. Dadurch ist sichergestellt, dass keine Dateien außerhalb des public Ordners über eine URL aufgerufen werden können. Für unsere Webanwendung erstellen wir daher die vHost-Adresse http://quickstart/.

Wir erstellen daher einen neuen vHost mit folgenden Einstellungen (Die Pfade sind anzupassen):

ServerName quickstart
DocumentRoot "/var/www/quickstart/public"
# Windows ~ DocumentRoot "C:/server/htdocs/quickstart/public"

[Bearbeiten] Das Layout erstellen

Widmen wir uns nun unserer eigentlichen Webanwendung.

Die Seitendarstellung unserer Anwendung im Browser enthält bestimmte Bereiche, die für mehrere oder alle View Skripte gleich wären. Das könnte z. B. das HTML Grundgeüst mit Header und Footer sein. Um doppelten Code zu vermeiden, lagern wie diese Bereiche in ein Layout Skript aus. Dazu nutzen wir die Zend Framework Komponente Zend_Layout. Wir können hier wieder auf das CLI Tool zurück greifen und führen im noch geöffneten Terminal folgenden Befehl aus:

zf enable layout

Diesen Kommandozeilenbefehl erläutert die Seite "CLI Tool: Zend Layout konfigurieren" genauer.

Unser Layout Skript ist die Datei application/layouts/scripts/layout.phtml. Wir öffnen diese Datei mit einem Editor und fügen ein simples HTML-Grundgerüst ein:

<?php echo $this->doctype(); ?> 
<html>
  <head>
    <?php echo $this->headMeta()->setCharset('utf-8'); // nur für HTML5 ?>
    <?php echo $this->headTitle('Quickstart'); ?>
  </head>
  <body>
    <?php echo $this->layout()->content; ?>
  </body>
</html>

In der Datei application/configs/application.ini legen wir nun fest, welchen DOCTYPE wir verwenden wollen:

# am Ende von [production]
resources.view.doctype = "HTML5"

Alternativ können wir den DOCTYPE auch direkt im Layout Skript definieren:

<?php echo $this->doctype('HTML5'); ?>

[Bearbeiten] Das Model erstellen

Wie bereits in der Einleitung erwähnt, soll unser erstes Projekt eine Gästebuchanwendung sein. Überlegen wir uns nun daher, welche Eigenschaften ein Gästebuch (guestbook) besitzt. Typischerweise ist es eine Liste von Einträgen mit einem Kommentar (comment), einem Zeitstempel (timestamp) und oft auch einer E-Mail-Adresse (email). Angenommen wir speichern diese Gästebucheinträge in einer Datenbank, dann wollen wir auch einen eindeutigen Identifikator (id) für jeden einzelnen Eintrag.

Wir erstellen daher eine Gästebucheintrag-Klasse mit diesen Eigenschaften und nutzen dazu wieder das CLI Tool:

zf create model GuestbookEntry

Dieser Befehl erstellt die Datei application/models/GuestbookEntry.php mit folgender Klasse:

<?php
class Application_Model_GuestbookEntry
{
}

Diese Klasse erweitern wir nun um ihre Eigenschaften und fügen Methoden hinzu, die das Manipulieren der Eigenschaften erlauben:

<?php
 
class Application_Model_GuestbookEntry
{
    protected $comment;
    protected $created;
    protected $email;
    protected $id;
 
    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }
    public function __set($name, $value)
    {
        $method = 'set' . ucfirst($name);
        if (!method_exists($this, $method)) {
            throw new Exception('Invalid guestbook entry property');
        }
        $this->$method($value);
    }
    public function __get($name)
    {
        $method = 'get' . ucfirst($name);
        if (!method_exists($this, $method)) {
            throw new Exception('Invalid guestbook entry property');
        }
        return $this->$method();
    }
    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }
    public function setComment($comment)
    {
        $this->comment = (string) $comment;
        return $this;
    }
    public function getComment()
    {
        return $this->comment;
    }
    public function setCreated($created)
    {
        $this->created = $created;
        return $this;
    }
    public function getCreated()
    {
        return $this->created;
    }
    public function setEmail($email)
    {
        $this->email = (string) $email;
        return $this;
    }
    public function getEmail()
    {
        return $this->email;
    }
    public function setId($id)
    {
        $this->id = (int) $id;
        return $this;
    }
    public function getId()
    {
        return $this->id;
    }
}

__get() und __set() ermöglichen einen bequemen Zugriff auf die Eigenschaften eines Eintrags, indem sie auf die Getter und Setter verweisen. Um z. B. auf einen Kommentar zuzugreifen, können wir statt $guestbookEntry->getComment() einfach $guestbookEntry->comment verwenden. Außerdem stellen sie sicher, dass nur diejenigen Eigenschaften im Gästebucheintrag verfügbar sind, die wir freigegeben haben.

[Bearbeiten] Eine Datenbank erstellen

Wir erstellen eine Datenbank mit dem Namen quickstart und erstellen darin die Tabelle guestbook. Der SQL-Befehl zum Erstellen der Tabelle lautet wie folgt:

CREATE TABLE `guestbook` (
`id` INT( 10 ) NOT NULL  AUTO_INCREMENT,
`email` VARCHAR( 50 ) NOT NULL ,
`comment` TEXT NOT NULL ,
`created` DATETIME NOT NULL ,
PRIMARY KEY ( `id` )
);
CREATE INDEX `id` ON `guestbook` (`id`);

Wir füllen die Tabelle zusätzlich noch mit zwei Einträgen. Hier der SQL-Befehl:

INSERT INTO `quickstart`.`guestbook` (
`id` , `email` , `comment` , `created`
)
VALUES (
NULL , 'ralph.schindler@zend.com', 'Hallo! Mir gefällt der Quickstart!', NOW( )
);
INSERT INTO `quickstart`.`guestbook` (
`id` , `email` , `comment` , `created`
)
VALUES (
NULL , 'foo@bar.com', 'Dieser Quickstart hat mir sehr geholfen.', NOW( )
);

Diese Befehle können z. B. in phpMyAdmin eingegeben werden.

[Bearbeiten] Einen Datenbankadapter konfigurieren

Damit unsere Webanwendung mit unserer Datenbank quickstart kommunizieren kann, müssen wir die Datenbankverbindung einrichten. Dazu können wir wieder das CLI Tool nutzen, indem wir folgenden Befehl ausführen:

zf configure dbadapter "adapter=Pdo_Mysql&username=root&password=pw&dbname=quickstart" development

Dieser Befehl ist natürlich anzupassen und wird auf der Seite "CLI Tool: Eine Datenbankverbindung konfigurieren" genauer erläutert.

[Bearbeiten] Einen Mapper erstellen

Nun erstellen wir einen Data Mapper. Dieser "mappt" unser Domain Objekt (Application_Model_GuestbookEntry) auf unsere Datenquelle: die Tabelle guestbook in unserer Datenbank quickstart. Da es sich hierbei um eine SQL-Datenbank handelt, müssten wir SQL-Befehle zum Lesen und Speichern unseres Domain Objekts im Data Mapper implementieren. Da das Zend Framework für solche Datenbankaktionen die Zend_Db Komponente bereitstellt, nutzen wir stattdessen deren Klassen. Für unsere Webanwendung heißt das, dass unser Data Mapper Zend_Db_Table zum Lesen und Speichern unserer Gästebucheinträge nutzt.

Wir erstellen also als erstes mit Hilfe des CLI Tools eine DbTable-Klasse, die Zend_Db_Table_Abstract erweitert:

zf create dbtable Guestbook guestbook

Dieser Befehl wird auf der Seite "CLI Tool: DbTable-Klassen erstellen" genauer erläutert. Er erstellt die Datei application/models/DbTable/Guestbook.php, die die Klasse Application_Model_DbTable_Guestbook enthält. Diese Klasse wird unser Data Mapper für den Zugriff auf die Datenbank nutzen.

Wir erstellen nun den Data Mapper und speichern dazu in der neuen Datei application/models/mappers/GuestbookEntry.php folgende Klasse:

<?php
 
class Application_Model_Mapper_GuestbookEntry
{
    protected $dao;
 
    public function setDao($dao)
    {
        if (is_string($dao)) {
            $dao = new $dao();
        }
        $this->dao = $dao;
        return $this;
    }
    public function getDao()
    {
        if (null === $this->dao) {
            $this->setDao('Application_Model_DbTable_Guestbook');
        }
        return $this->dao;
    }
    public function save(Application_Model_GuestbookEntry $guestbookEntry)
    {
        $data = array(
            'email'   => $guestbookEntry->email,
            'comment' => $guestbookEntry->comment,
            'created' => date('Y-m-d H:i:s'),
        );
        if (null === ($id = $guestbookEntry->id)) {
            unset($data['id']);
            $this->getDao()->insert($data);
        } else {
            $this->getDao()->update($data, array('id = ?' => $id));
        }
    }
    public function find($id, Application_Model_GuestbookEntry $guestbookEntry)
    {
        $result = $this->getDao()->find($id);
        if (0 == count($result)) {
            return;
        }
        $row = $result->current();
        $guestbookEntry->id      = $row->id;
        $guestbookEntry->email   = $row->email;
        $guestbookEntry->comment = $row->comment;
        $guestbookEntry->created = $row->created;
    }
    public function fetchAll()
    {
        $resultSet = $this->getDao()->fetchAll();
        $entries   = array();
        foreach ($resultSet as $row) {
            $entry = new Application_Model_GuestbookEntry();
            $entry->id      = $row->id;
            $entry->email   = $row->email;
            $entry->comment = $row->comment;
            $entry->created = $row->created;
            $entries[] = $entry;
        }
        return $entries;
    }
}

[Bearbeiten] Ein Formular erstellen

Unsere Gästebuchanwendung benötigt natürlich auch ein Formular, in das Gäste ihre Einträge eingeben können. Zur Erstellung der Formularklasse nutzen wir wieder das CLI Tool:

zf create form GuestbookEntry

Diesen Kommandozeilenbefehl erläutert die Seite "CLI Tool: Formulare erstellen" genauer.

Dies erstellt die Klasse Application_Form_GuestbookEntry in application/forms/GuestbookEntry.php. Wir öffnen nun diese Datei mit einem Editor und erweitern sie:

<?php
 
class Application_Form_GuestbookEntry extends Zend_Form
{
    public function init()
    {
        // Anzeigemethode ist POST
        $this->setMethod('post');
        // Ein Eingabefeld für die E-Mail-Adresse
        $this->addElement('text', 'email', array(
            'label'      => 'Deine E-Mail-Adresse:',
            'required'   => true,
            'filters'    => array('StringTrim', 'StripTags'),
            'validators' => array(
                'EmailAddress',
                array(
                    'validator' => 'StringLength',
                    'options' => array(0, 50)
                )
            )
        ));
        // Ein Textfeld für die Nachricht
        $this->addElement('textarea', 'comment', array(
            'label'    => 'Deine Nachricht:',
            'required' => true,
            'filters'  => array('StripTags'),
        ));
        // CAPTCHA Element
        $this->addElement('captcha', 'captcha', array(
            'label'    => 'Bitte gib die folgenden 5 Buchstaben ein:',
            'required' => true,
            'captcha'  => array(
                'captcha' => 'Figlet',
                'wordLen' => 5,
                'timeout' => 300
            )
        ));
        // 'Speichern' Button
        $this->addElement('submit', 'submit', array(
            'ignore' => true,
            'label'  => 'Speichern',
        ));
        // Ein Element zum Schutz vor CSRF (Cross-Site Request Forgery)
        $this->addElement('hash', 'csrf', array(
            'ignore' => true,
        ));
    }
}

[Bearbeiten] Einen Controller erstellen

Nun erstellen wir einen Controller, der die eigentliche Funktionalität unserer Webanwendung unter Verwendung der bisher erstellten Klassen herstellt. Wir nutzen wieder das CLI Tool:

zf create controller Guestbook

Dies erstellt den GuestbookController, der außerdem die indexAction enthält. Diese soll unser Gästebuch anzeigen. Damit neue Gästebucheinträge gespeichert werden können, erstellen wir innerhalb des GuestbookControllers eine weitere Action, die signAction:

zf create action sign Guestbook

Die Seite "CLI Tool: Controller und Actions erstellen" erläutert diese Befehle genauer.

Wir öffnen die Datei application/controllers/GuestbookController.php und erweitern den GuestbookController wie folgt:

<?php
 
class GuestbookController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $mapper = new Application_Model_Mapper_GuestbookEntry();
        $this->view->entries = $mapper->fetchAll();
    }
    public function signAction()
    {
        $form = new Application_Form_GuestbookEntry();
        if ($this->getRequest()->isPost()) {
            if ($form->isValid($this->getRequest()->getPost())) {
                $entry  = new Application_Model_GuestbookEntry($form->getValues());
                $mapper = new Application_Model_Mapper_GuestbookEntry();
                $mapper->save($entry);
                return $this->_helper->redirector('index');
            }
        }
        $this->view->form = $form;
    }
}

Die Variablen, die der GuestbookController an das View übergeben hat, müssen noch in den entsprechenden View-Skripten ausgegeben werden.

application/views/scripts/guestbook/index.phtml:

<p><a href="<?php echo $this->url(
    array(
        'controller' => 'guestbook',
        'action'     => 'sign'
    ), 'default', true); ?>">Hinterlasse einen G&auml;stebucheintrag</a></p>
<p>Eintr&auml;ge:<p>
<dl>
    <?php foreach ($this->entries as $entry): ?>
    <dt><?php echo $this->escape($entry->email); ?></dt>
    <dd><?php echo $this->escape($entry->comment); ?></dd>
    <?php endforeach; ?>
</dl>

application/views/scripts/guestbook/sign.phtml:

<p>Bitte nutze dieses Formular, um eine Nachricht im G&auml;stebuch zu hinterlassen!</p>
<?php echo $this->form; ?>

So sieht die fertige Webanwendung im Browser aus:

http://quickstart/guestbook

Datei:Quickstart_indexAction.png

http://quickstart/guestbook/sign

Datei:Quickstart_signAction.png

Persönliche Werkzeuge