| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 21819 -->
- <!-- Reviewed: 21819 -->
- <sect1 id="learning.quickstart.create-model">
- <title>Ein Modell und eine Datenbanktabelle erstellen</title>
- <para>
- Bevor wir anfangen, wollen wir uns überlegen: Wo werden diese Klassen leben, und wie werden wir
- sie finden? Das Standardprojekt, welches wir erstellt haben, instanziert einen Autoloader. Wir
- können ihm andere Autoloader anhängen, damit er weiss, wo andere Klassen zu finden sind.
- Typischerweise wollen wir, dass unsere verschiedenen MVC Klassen im selben Baum gruppiert sind
- -- in diesem Fall <filename>application/</filename> -- und meistens ein gemeinsames Präfix
- verwenden.
- </para>
- <para>
- <classname>Zend_Controller_Front</classname> kennt den Begriff von "Modulen", welche
- individuelle Mini-Anwendungen sind. Module mimen die Verzeichnisstruktur, welche das
- <command>zf</command>-Tool unter <filename>application/</filename> einrichtet, und von allen
- Klassen darin wird angenommen, dass sie mit einen gemeinsamen Präfix beginnen, dem Namen des
- Moduls. <filename>application/</filename> selbst ist ein Modul -- das "default" oder
- "application" Modul. Als solches richten wir das Autoloading für Ressourcen in diesem
- Verzeichnis ein.
- </para>
- <para>
- <classname>Zend_Application_Module_Autoloader</classname> bietet die Funktionalität, welche
- benötigt wird, um die verschiedenen Ressourcen unter einem Modul mit den richtigen
- Verzeichnissen zu verbinden, und auch einen standardmäßigen Namensmechanismus. Standardmäßig
- wird eine Instanz der Klasse wärend der Initialisierung des Bootstrap-Objekts erstellt;
- unser Application Bootstrap verwendet standardmäßig das Modulpräfix "Application". Daher
- beginnen alle unsere Modelle, Formulare, und Tabellenklassen mit dem Klassenpräfix
- "Application_".
- </para>
- <para>
- Überlegen wir uns nun, was ein Guestbook ausmacht. Typischerweise ist das einfach eine
- Liste von Einträgen mit einem <emphasis>Kommentar</emphasis> (comment), einem
- <emphasis>Zeitpunkt</emphasis> (timestamp) und oft einer <emphasis>Email-Adresse</emphasis>.
- Angenommen wir speichern diese in einer Datenbank, dann wollen wir auch einen
- <emphasis>eindeutigen Identifikator</emphasis> für jeden Eintrag. Wir wollen in der Lage
- sein, einen Eintrag zu speichern, individuelle Einträge zu holen, und alle Einträge zu
- empfangen. Als solches könnte das Modell einer einfachen Guestbook-<acronym>API</acronym>
- wie folgt aussehen:
- </para>
- <programlisting language="php"><![CDATA[
- // application/models/Guestbook.php
- class Application_Model_Guestbook
- {
- protected $_comment;
- protected $_created;
- protected $_email;
- protected $_id;
- public function __set($name, $value);
- public function __get($name);
- public function setComment($text);
- public function getComment();
- public function setEmail($email);
- public function getEmail();
- public function setCreated($ts);
- public function getCreated();
- public function setId($id);
- public function getId();
- }
- class Application_Model_GuestbookMapper
- {
- public function save(Application_Model_Guestbook $guestbook);
- public function find($id);
- public function fetchAll();
- }
- ]]></programlisting>
- <para>
- <methodname>__get()</methodname> und <methodname>__set()</methodname> bieten uns bequeme
- Mechanismen an um auf individuelle Eigenschaften von Einträgen zuzugreifen und auf andere
- Getter und Setter zu verweisen. Sie stellen auch sicher, dass nur Eigenschaften im Objekt
- vorhanden sind, die wir freigegeben haben.
- </para>
- <para>
- <methodname>find()</methodname> und <methodname>fetchAll()</methodname> bieten die Fähigkeit,
- einen einzelnen Eintrag oder alle Einträge zu holen, wärend <methodname>save()</methodname>
- das Speichern der Einträge im Datenspeicher übernimmt.
- </para>
- <para>
- Von hier an können wir über die Einrichtung unserer Datenbank nachdenken.
- </para>
- <para>
- Zuerst muss unsere <classname>Db</classname>-Ressource initialisiert werden. Wie bei
- <classname>Layout</classname> und <classname>View</classname> kann die Konfiguration für die
- <classname>Db</classname>-Ressource angegeben werden. Dies kann mit dem Befehl
- <command>zf configure db-adapter</command> getan werden:
- </para>
- <programlisting language="shell"><![CDATA[
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
- > production
- A db configuration for the production has been written to the application config file.
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
- > testing
- A db configuration for the production has been written to the application config file.
- % zf configure db-adapter \
- > 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
- > development
- A db configuration for the production has been written to the application config file.
- ]]></programlisting>
- <para>
- Jetzt muss die Datei <filename>application/configs/application.ini</filename> bearbeitet
- werden, und man kann sehen, dass die folgenden Zeilen in den betreffenden Abschnitten
- hinzugefügt wurden.
- </para>
- <programlisting language="ini"><![CDATA[
- ; application/configs/application.ini
- [production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
- [testing : production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
- [development : production]
- ; ...
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
- ]]></programlisting>
- <para>
- Die endgültige Konfigurationsdatei sollte wie folgt aussehen:
- </para>
- <programlisting language="ini"><![CDATA[
- ; application/configs/application.ini
- [production]
- phpSettings.display_startup_errors = 0
- phpSettings.display_errors = 0
- bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
- bootstrap.class = "Bootstrap"
- appnamespace = "Application"
- resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
- resources.frontController.params.displayExceptions = 0
- resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
- resources.view[] =
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"
- [staging : production]
- [testing : production]
- phpSettings.display_startup_errors = 1
- phpSettings.display_errors = 1
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"
- [development : production]
- phpSettings.display_startup_errors = 1
- phpSettings.display_errors = 1
- resources.db.adapter = "PDO_SQLITE"
- resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
- ]]></programlisting>
- <para>
- Es ist zu beachten, dass die Datenbank(en) unter <filename>data/db/</filename> gespeichert
- wird. Diese Verzeichnisse sind zu erstellen und weltweit-schreibbar zu machen. Auf
- Unix-artigen Systemen kann man das wie folgt durchführen:
- </para>
- <programlisting language="shell"><![CDATA[
- % mkdir -p data/db; chmod -R a+rwX data
- ]]></programlisting>
- <para>
- Unter Windows muss man die Verzeichnisse im Explorer erstellen und die Zugriffsrechte so
- setzen, dass jeder in das Verzeichnis schreiben darf.
- </para>
- <para>
- Ab diesem Punkt haben wir eine Verbindung zu einer Datenbank; in unserem Fall ist es eine
- Verbindung zu einer Sqlite-Datenbank, die in unserem <filename>application/data/</filename>
- Verzeichnis ist. Erstellen wir also eine einfache Tabelle, die unsere Guestbook-Einträge
- enthalten wird.
- </para>
- <programlisting language="sql"><![CDATA[
- -- scripts/schema.sqlite.sql
- --
- -- Man muss das Datenbank Schema mit diesem SQL laden.
- CREATE TABLE guestbook (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- email VARCHAR(32) NOT NULL DEFAULT 'noemail@test.com',
- comment TEXT NULL,
- created DATETIME NOT NULL
- );
- CREATE INDEX "id" ON "guestbook" ("id");
- ]]></programlisting>
- <para>
- Und damit wir gleich einige Arbeitsdaten haben, fügen wir ein paar Zeilen ein,
- um unsere Anwendung interessant zu machen.
- </para>
- <programlisting language="sql"><![CDATA[
- -- scripts/data.sqlite.sql
- --
- -- Man kann damit beginnen die Datenbank zu befüllen, indem die folgenden SQL
- -- Anweisungen ausgeführt werden.
- INSERT INTO guestbook (email, comment, created) VALUES
- ('ralph.schindler@zend.com',
- 'Hallo! Hoffentlich geniesst Ihr dieses Beispiel einer ZF Anwendung!
- DATETIME('NOW'));
- INSERT INTO guestbook (email, comment, created) VALUES
- ('foo@bar.com',
- 'Baz baz baz, baz baz Baz baz baz - baz baz baz.',
- DATETIME('NOW'));
- ]]></programlisting>
- <para>
- Jetzt haben wir sowohl das Schema als auch einige Daten definiert. Schreiben wir also ein
- Skript, das wir jetzt ausführen können, um diese Datenbank zu erstellen. Natürlich wird das
- nicht in der Produktion benötigt, aber dieses Skriupt hilft Entwicklern die Notwendigkeiten
- der Datenbank lokal zu erstellen, damit sie eine voll funktionsfähige Anwendung haben. Das
- Skript ist als <filename>scripts/load.sqlite.php</filename> mit dem folgenden Inhalt zu
- erstellen:
- </para>
- <programlisting language="php"><![CDATA[
- // scripts/load.sqlite.php
- /**
- * Skript für das Erstellen und Laden der Datenbank
- */
- // Initialisiert den Pfad und das Autoloading der Anwendung
- defined('APPLICATION_PATH')
- || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
- set_include_path(implode(PATH_SEPARATOR, array(
- APPLICATION_PATH . '/../library',
- get_include_path(),
- )));
- require_once 'Zend/Loader/Autoloader.php';
- Zend_Loader_Autoloader::getInstance();
- // Definiert einige CLI Optionen
- $getopt = new Zend_Console_Getopt(array(
- 'withdata|w' => 'Datenbank mit einigen Daten laden',
- 'env|e-s' => "Anwendungsumgebung für welche die Datenbank "
- . "erstellt wird (Standard ist Development)",
- 'help|h' => 'Hilfe -- Verwendung',
- ));
- try {
- $getopt->parse();
- } catch (Zend_Console_Getopt_Exception $e) {
- // Schlechte Option übergeben: Verwendung ausgeben
- echo $e->getUsageMessage();
- return false;
- }
- // Wenn Hilfe angefragt wurde, Verwendung ausgeben
- if ($getopt->getOption('h')) {
- echo $getopt->getUsageMessage();
- return true;
- }
- // Werte basierend auf ihrer Anwesenheit oder Abwesenheit von CLI Optionen initialisieren
- $withData = $getopt->getOption('w');
- $env = $getopt->getOption('e');
- defined('APPLICATION_ENV')
- || define('APPLICATION_ENV', (null === $env) ? 'development' : $env);
- // Zend_Application initialisieren
- $application = new Zend_Application(
- APPLICATION_ENV,
- APPLICATION_PATH . '/configs/application.ini'
- );
- // Die DB Ressource initialisieren und empfangen
- $bootstrap = $application->getBootstrap();
- $bootstrap->bootstrap('db');
- $dbAdapter = $bootstrap->getResource('db');
- // Den Benutzer informieren was abgeht
- // (wir erstellen hier aktuell eine Datenbank)
- if ('testing' != APPLICATION_ENV) {
- echo 'Schreiben in die Guestbook Datenbank (control-c um abzubrechen): ' . PHP_EOL;
- for ($x = 5; $x > 0; $x--) {
- echo $x . "\r"; sleep(1);
- }
- }
- // Prüfen um zu sehen ob wir bereits eine Datenbankdatei haben
- $options = $bootstrap->getOption('resources');
- $dbFile = $options['db']['params']['dbname'];
- if (file_exists($dbFile)) {
- unlink($dbFile);
- }
- // Dieser Block führt die aktuellen Statements aus welche von der Schemadatei
- // geladen werden.
- try {
- $schemaSql = file_get_contents(dirname(__FILE__) . '/schema.sqlite.sql');
- // Die Verbindung direkt verwenden um SQL im Block zu laden
- $dbAdapter->getConnection()->exec($schemaSql);
- chmod($dbFile, 0666);
- if ('testing' != APPLICATION_ENV) {
- echo PHP_EOL;
- echo 'Datenbank erstellt';
- echo PHP_EOL;
- }
- if ($withData) {
- $dataSql = file_get_contents(dirname(__FILE__) . '/data.sqlite.sql');
- // Die Verbindung direkt verwenden um SQL in Blöcken zu laden
- $dbAdapter->getConnection()->exec($dataSql);
- if ('testing' != APPLICATION_ENV) {
- echo 'Daten geladen.';
- echo PHP_EOL;
- }
- }
- } catch (Exception $e) {
- echo 'EIN FEHLER IST AUFGETRETEN:' . PHP_EOL;
- echo $e->getMessage() . PHP_EOL;
- return false;
- }
- // dieses Skript von der Kommandozeile aus aufgerufen
- return true;
- ]]></programlisting>
- <para>
- Jetzt führen wir dieses Skript aus. Von einem Terminal oder der DOS Kommandozeile ist das
- folgende zu tun:
- </para>
- <programlisting language="shell"><![CDATA[
- % php scripts/load.sqlite.php --withdata
- ]]></programlisting>
- <para>
- Man sollte eine ähnliche Ausgabe wie folgt sehen:
- </para>
- <programlisting language="text"><![CDATA[
- path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
- Schreiben in die Guestbook Datenbank (control-c um abzubrechen):
- 1
- Datenbank erstellt
- Daten geladen.
- ]]></programlisting>
- <para>
- Jetzt haben wir eine voll funktionsfähige Datenbank und eine Tabelle für unsere Guestbook
- Anwendung. Unsere nächsten paar Schritte sind die Ausarbeitung unseres Anwendungscodes. Das
- schliesst das Bauen einer Datenquelle (in unserem Fall verwenden wir
- <classname>Zend_Db_Table</classname>), und einen Daten Mapper um diese Datenquelle mit
- unserem Domain Modell zu verbinden, ein. Letztendlich erstellen wir den Controller, der mit diesem
- Modell interagiert, damit sowohl existierende Einträge angezeigt als auch neue Einträge
- bearbeitet werden.
- </para>
- <para>
- Wir verwenden ein <ulink
- url="http://martinfowler.com/eaaCatalog/tableDataGateway.html">Table Data
- Gateway</ulink>, um uns mit unserer Datenquelle zu verbinden;
- <classname>Zend_Db_Table</classname> bietet diese Funktionalität. Um anzufangen erstellen
- wir eine <classname>Zend_Db_Table</classname>-basierende Tabellenklasse. Wie wir es für
- Layouts und den Datenbankadapter getan haben, können wir das <command>zf</command> Tool
- verwenden um uns zu assistieren, indem der Befehl <command>create db-table</command>
- verwendet wird. Dieser benötigt mindestens zwei Argumente, den Namen, mit dem man auf die
- Klasse referenzieren will, und die Datenbanktabelle auf die sie zeigt.
- </para>
- <programlisting language="shell"><![CDATA[
- % zf create db-table Guestbook guestbook
- Creating a DbTable at application/models/DbTable/Guestbook.php
- Updating project profile 'zfproject.xml'
- ]]></programlisting>
- <para>
- Wenn man den Verzeichnisbaum ansieht, dann wird man feststellen, dass ein neues Verzeichnis
- <filename>application/models/DbTable/</filename> zusammen mit der Datei
- <filename>Guestbook.php</filename> erstellt wurde. Wenn man die Datei öffnet, wird man den
- folgenden Inhalt sehen:
- </para>
- <programlisting language="php"><![CDATA[
- // application/models/DbTable/Guestbook.php
- /**
- * Das ist die DbTable Klasse für die Guestbook Tabelle.
- */
- class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
- {
- /** Tabellenname */
- protected $_name = 'guestbook';
- }
- ]]></programlisting>
- <para>
- Das Klassenpräfix ist zu beachten: <classname>Application_Model_DbTable</classname>. Das
- Klassenpräfix für unser Modul "Application" ist das erste Segment, und dann haben wir die
- Komponente "Model_DbTable"; die letztere verweist auf das Verzeichnis
- <filename>models/DbTable/</filename> des Moduls.
- </para>
- <para>
- Alles das ist wirklich notwendig, wenn <classname>Zend_Db_Table</classname> erweitert wird
- um einen Tabellennamen anzubieten und optional den primären Schlüssel (wenn es nicht die
- "id" ist).
- </para>
- <para>
- Jetzt erstellen wir einen <ulink
- url="http://martinfowler.com/eaaCatalog/dataMapper.html">Data Mapper</ulink>. Ein
- <emphasis>Data Mapper</emphasis> bildet ein Domain Objekt in der Datenbank ab. In unserem
- Fall bildet es unser Modell <classname>Application_Model_Guestbook</classname> auf unsere
- Datenquelle, <classname>Application_Model_DbTable_Guestbook</classname>, ab. Eine typische
- <acronym>API</acronym> für einen Data Mapper ist wie folgt:
- </para>
- <programlisting language="php"><![CDATA[
- // application/models/GuestbookMapper.php
- class Application_Model_GuestbookMapper
- {
- public function save($model);
- public function find($id, $model);
- public function fetchAll();
- }
- ]]></programlisting>
- <para>
- Zusätzlich zu diesen Methoden fügen wir Methoden für das Setzen und Holen des Table Data
- Gateways hinzu. Um die initiale Klasse zu erstellen, kann das <command>zf</command> CLI
- Tool verwendet werden:
- </para>
- <programlisting language="shell"><![CDATA[
- % zf create model GuestbookMapper
- Creating a model at application/models/GuestbookMapper.php
- Updating project profile '.zfproject.xml'
- ]]></programlisting>
- <para>
- Jetzt muss die Klasse <classname>Application_Model_GuestbookMapper</classname>, welche in
- <filename>application/models/GuestbookMapper.php</filename> zu finden ist, so
- geändert werden, dass sie wie folgt aussieht:
- </para>
- <programlisting language="php"><![CDATA[
- // application/models/GuestbookMapper.php
- class Application_Model_GuestbookMapper
- {
- protected $_dbTable;
- public function setDbTable($dbTable)
- {
- if (is_string($dbTable)) {
- $dbTable = new $dbTable();
- }
- if (!$dbTable instanceof Zend_Db_Table_Abstract) {
- throw new Exception('Ungültiges Table Data Gateway angegeben');
- }
- $this->_dbTable = $dbTable;
- return $this;
- }
- public function getDbTable()
- {
- if (null === $this->_dbTable) {
- $this->setDbTable('Application_Model_DbTable_Guestbook');
- }
- return $this->_dbTable;
- }
- public function save(Application_Model_Guestbook $guestbook)
- {
- $data = array(
- 'email' => $guestbook->getEmail(),
- 'comment' => $guestbook->getComment(),
- 'created' => date('Y-m-d H:i:s'),
- );
- if (null === ($id = $guestbook->getId())) {
- unset($data['id']);
- $this->getDbTable()->insert($data);
- } else {
- $this->getDbTable()->update($data, array('id = ?' => $id));
- }
- }
- public function find($id, Application_Model_Guestbook $guestbook)
- {
- $result = $this->getDbTable()->find($id);
- if (0 == count($result)) {
- return;
- }
- $row = $result->current();
- $guestbook->setId($row->id)
- ->setEmail($row->email)
- ->setComment($row->comment)
- ->setCreated($row->created);
- }
- public function fetchAll()
- {
- $resultSet = $this->getDbTable()->fetchAll();
- $entries = array();
- foreach ($resultSet as $row) {
- $entry = new Application_Model_Guestbook();
- $entry->setId($row->id)
- ->setEmail($row->email)
- ->setComment($row->comment)
- ->setCreated($row->created);
- $entries[] = $entry;
- }
- return $entries;
- }
- }
- ]]></programlisting>
- <para>
- Jetzt ist es Zeit unsere Modellklasse zu erstellen. Wir machen dies, indem wieder das
- Kommando <command>zf create model</command> verwendet wird:
- </para>
- <programlisting language="shell"><![CDATA[
- % zf create model Guestbook
- Creating a model at application/models/Guestbook.php
- Updating project profile '.zfproject.xml'
- ]]></programlisting>
- <para>
- Wir verändern diese leere <acronym>PHP</acronym>-Klasse, um das Model einfach mit Daten
- zu füllen, indem ein Array an Daten entweder an den Constructor oder an die
- Methode <methodname>setOptions()</methodname> übergeben wird. Das endgültige Modell, welches
- in <filename>application/models/Guestbook.php</filename> ist, sollte wie folgt aussehen:
- </para>
- <programlisting language="php"><![CDATA[
- // application/models/Guestbook.php
- class Application_Model_Guestbook
- {
- 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' . $name;
- if (('mapper' == $name) || !method_exists($this, $method)) {
- throw new Exception('Ungültige Guestbook Eigenschaft');
- }
- $this->$method($value);
- }
- public function __get($name)
- {
- $method = 'get' . $name;
- if (('mapper' == $name) || !method_exists($this, $method)) {
- throw new Exception('Ungültige Guestbook Eigenschaft');
- }
- 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($text)
- {
- $this->_comment = (string) $text;
- return $this;
- }
- public function getComment()
- {
- return $this->_comment;
- }
- public function setEmail($email)
- {
- $this->_email = (string) $email;
- return $this;
- }
- public function getEmail()
- {
- return $this->_email;
- }
- public function setCreated($ts)
- {
- $this->_created = $ts;
- return $this;
- }
- public function getCreated()
- {
- return $this->_created;
- }
- public function setId($id)
- {
- $this->_id = (int) $id;
- return $this;
- }
- public function getId()
- {
- return $this->_id;
- }
- }
- ]]></programlisting>
- <para>
- Um diese Elemente alle zusammen zu verbinden, erstellen wir zuletzt einen
- Guestbook Controller, der die Einträge auflistet, welche aktuell in der Datenbank sind.
- </para>
- <para>
- Um einen neuen Controller zu erstellen, muss das Kommando
- <command>zf create controller</command> verwendet werden:
- </para>
- <programlisting language="shell"><![CDATA[
- % zf create controller Guestbook
- Creating a controller at
- application/controllers/GuestbookController.php
- Creating an index action method in controller Guestbook
- Creating a view script for the index action method at
- application/views/scripts/guestbook/index.phtml
- Creating a controller test file at
- tests/application/controllers/GuestbookControllerTest.php
- Updating project profile '.zfproject.xml'
- ]]></programlisting>
- <para>
- Das erstellt einen neuen Controller, <classname>GuestbookController</classname>, in
- <filename>application/controllers/GuestbookController.php</filename> mit einer einzelnen
- Aktions Methode, <methodname>indexAction()</methodname>. Er erstellt auch ein View Skript
- Verzeichnis für den Controller, <filename>application/views/scripts/guestbook/</filename>,
- mit einem View Skript für die Index Aktion.
- </para>
- <para>
- Wir verwenden die "index" Aktion als Landeseite, um alle Guestbook Einträge anzusehen.
- </para>
- <para>
- Jetzt betrachten wir die grundsätzliche Anwendungslogik. Bei einem Treffer auf
- <methodname>indexAction()</methodname> zeigen wir alle Guestbook Einträge an. Das würde wie
- folgt aussehen:
- </para>
- <programlisting language="php"><![CDATA[
- // application/controllers/GuestbookController.php
- class GuestbookController extends Zend_Controller_Action
- {
- public function indexAction()
- {
- $guestbook = new Application_Model_GuestbookMapper();
- $this->view->entries = $guestbook->fetchAll();
- }
- }
- ]]></programlisting>
- <para>
- Und natürlich benötigen wir ein View Skript um damit weiterzumachen.
- <filename>application/views/scripts/guestbook/index.phtml</filename> ist zu bearbeiten damit
- sie wie folgt aussieht:
- </para>
- <programlisting language="php"><![CDATA[
- <!-- application/views/scripts/guestbook/index.phtml -->
- <p><a href="<?php echo $this->url(
- array(
- 'controller' => 'guestbook',
- 'action' => 'sign'
- ),
- 'default',
- true) ?>">Im Guestbook eintragen</a></p>
- Guestbook Einträge: <br />
- <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>
- ]]></programlisting>
- <note>
- <title>Checkpoint</title>
- <para>
- Jetzt gehen wir auf "http://localhost/guestbook". Man sollte das folgende im Browser
- sehen:
- </para>
- <para>
- <inlinegraphic width="525" scale="100" align="center" valign="middle"
- fileref="figures/learning.quickstart.create-model.png" format="PNG" />
- </para>
- </note>
- <note>
- <title>Das Datenlade-Skript verwenden</title>
- <para>
- Das Datenlade-Skript, welches in diesem Kapitel beschrieben wird
- (<filename>scripts/load.sqlite.php</filename>) kann verwendet werden, um die Datenbank
- für jede Umgebung zu erstellen, die man definiert hat, sowie sie mit Beispieldaten zu
- laden. Intern verwendet es <classname>Zend_Console_Getopt</classname>, was es erlaubt,
- eine Anzahl von Kommandozeilenschalter anzugeben. Wenn man den "-h" oder "--help"
- Schalter übergibt, werden die folgenden Optionen angegeben:
- </para>
- <programlisting language="php"><![CDATA[
- Usage: load.sqlite.php [ options ]
- --withdata|-w Datenbank mit einigen Daten laden
- --env|-e [ ] Anwendungsumgebung für welche die Datenbank erstellt wird
- (Standard ist Development)
- --help|-h Hilfe -- Verwendung)]]
- ]]></programlisting>
- <para>
- Der "-e" Schalter erlaubt es, den Wert anzugeben, der für die Konstante
- <constant>APPLICATION_ENV</constant> verwendet wird -- welcher es erlaubt, eine SQLite
- Datenbank für jede Umgebung zu erstellen, die man definiert. Man sollte sicherstellen,
- dass das Skript für die Umgebung gestartet wird, welche man für die eigene Anwendung
- ausgewählt hat, wenn man in Betrieb geht.
- </para>
- </note>
- </sect1>
|