Die zu erstellende Webseite soll Platz für ein Key-Visual, einen Header-Bereich, ein Menü und einen Bereich für den Inhalt und einen Footer bieten. Im Content-Bereich soll dynamischer Inhalt abhängig von einem URL-Parameter angezeigt werden. Grafisch betrachtet soll die Seite dann folgendes Aussehen haben:
sites/
testwebsite/
pres/
templates/
documentcontroller/erstellt werden. Diese dient später zur strukturierten Aufnahme der Template- und Controller- Dateien der Webseite.
Da das Framework für die Verwendung einer zentralen Bootstrap-Datei konzipiert wurde, über die alle Requests der Besucher abgehandelt werden, muss diese nun im Ordner testwebsite/ angelegt werden. Der Inhalt der Datei kann aus der aktuellen index.php der Dokumentationswebseite kopiert und wie folgt angepasst werden. Der Einfachheit wegen wird auf die Verwendung des FrontControllers verzichtet, da auch dies die Handhabung für den Einsteiger erleichtert.
// Page-Controller einbinden (APF-Core-Library)
include_once('./apps/core/pagecontroller/pagecontroller.php');
// Front-Controller einbinden
import('core::frontcontroller', 'Frontcontroller');
// Front-Controller erzeugen und konfigurieren
$fC = &Singleton::getInstance('Frontcontroller');
$fC->setContext('projectone');
// Request-Abarbeitung starten und Ergebnis zum Client senden
echo $fC->start('sites::testwebsite::pres::templates', 'website');In der Code-Darstellung sind bereits implizit weitere Vereinbarungen über die Struktur des Codes enthalten, die die weiteren Schritte beeinflussen.
<html>
<head>
<title>TestWebSite</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
[..]
</style>
</head>
<body>
<center>
<table width="800" border="0" cellpadding="0" cellspacing="0" class="table_layout">
<tr>
<td class="table_keyvisual">
K e y
<br />
V i s
<br />
u a l
</td>
<td class="table_header">
Header
</td>
</tr>
<tr>
<td class="table_menu">
<br />
Startseite
<br />
Impressum
</td>
<td class="table_content">
Content
</td>
</tr>
</table>
</center>
</body>
</html>http://localhost/testwebsite/<html>
<head>
<title>TestWebSite</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
[..]
</style>
</head>
<body>
<center>
<table width="800" border="0" cellpadding="0" cellspacing="0" class="table_layout">
<tr>
<td class="table_keyvisual">
K e y
<br />
V i s
<br />
u a l
</td>
<td class="table_header">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="header"
/>
</td>
</tr>
<tr>
<td class="table_menu">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="menu"
/>
</td>
<td class="table_content">
<core:importdesign
namespace="sites::testwebsite::pres::templates"
template="content"
/>
</td>
</tr>
</table>
</center>
</body>
</html>Header<br />
Startseite
<br />
ImpressumContenthttp://localhost/testwebsite/<br />
<a href="./?Seite=Startseite">Startseite</a>
<br />
<a href="./?Seite=Impressum">Impressum</a>mit den gewünschten Inhalten anzulegen. Da der Content im Inhaltsbereich angezeigt werden soll muss die dafür verantwortliche Template-Datei content.html wie folgt abgeändert werden:
<core:addtaglib
namespace="tools::html::taglib"
class="CreateDocumentFromFileTag"
prefix="doc"
name="createobject"
/>
<doc:createobject requestparam="Seite" defaultvalue="Startseite" />Eine weitere Möglichkeit bietet die Variante, die Inhalte aus einer Datenbank zu lesen und in den Inhaltsbereich der Seite einzubetten. Hierzu kann der Entwickler Gebrauch von einem Document-Controller machen, der dazu gedacht ist, dynamischen Inhalt zu erzeugen.
Zunächst muss dazu eine Tabelle in der Datenbank freier Wahl erzeugt werden, die den Inhalt aufnimmt. Diese kann mit folgendem SQL-Statement erzeugt werden:
CREATE TABLE demopage_content (
PageID tinyint(5) NOT NULL auto_increment,
PageURLName varchar(50) NOT NULL default '',
PageTitle varchar(50) NOT NULL default '',
PageContent text NOT NULL,
PRIMARY KEY (PageID),
UNIQUE KEY PageURLName (PageURLName),
KEY PageTitle (PageTitle)
) ENGINE=MyISAM;Ähnlich der unter 5.1. gezeigten Änderung muss nun die Datei content.html angepasst werden:
<@controller
namespace="sites::testwebsite::pres::documentcontroller"
class="content_v1_controller"
@>Mit diesem XML-Tag wird dem Page-Controller bekannt gemacht, dass zur Verarbeitung des aktuellen Templates einen Controller im Sinne des MVC-Patterns zu verwenden ist. Hierzu setzen wir einen (Document-)Controller ein. Diese von BaseDocumentController abgeleitete PHP-Klasse ist dann dafür verantwortlich, dass der dynamische Inhalt geladen und an der gewünschten Stelle ausgegeben wird.
Da die Inhalte aus der Datenbank gelesen werden wird zur Konnektierung der Datenbank die Komponente ConnectionManager verwendet. Die Controller-Datei
testwebsite/apps/sites/testwebsite/pres/documentcontroller/content_v1_controller.phpsoll mit folgendem Inhalt gefüllt werden:
import('tools::request', 'RequestHandler');
class content_v1_controller extends BaseDocumentController {
public function transformContent(){
$cM = &$this->getServiceObject('core::database','ConnectionManager');
$SQL = &$cM->getConnection('content-database');
// URL-Parameter beziehen
$page = RequestHandler::getValue('Seite','Startseite');
// Parameter gegen SQL-Injections absichern
$page = $SQL->escapeValue($page);
// Inhalt der Seite auslesen
$select = 'SELECT PageContent
FROM demopage_content
WHERE PageURLName = \''.$page.'\'
LIMIT 1';
$result = $SQL->executeTextStatement($select);
$data = $SQL->fetchData($result);
// Inhalt der Seite ausgeben
$this->setContent($data['PageContent']);
}
}Der Quelltext des Controllers sollte selbstredend sein. Im Groben beschrieben wird hier nichts anderes in PHP-Code abgebildet, wie in einem herkömmlichen Script auch stehen würde.
Um auf die Datenbank zugreifen zu können erwartet die MySQL-Komponente eine Konfigurationsdatei unter dem Pfad
testwebsite/apps/config/core/database/projectone/DEFAULT_connections.iniDer Dateiname setzt sich aus dem Pfad
testwebsite/apps/config/core/database/{CONTEXT}/und dem Namen
{ENVIRONMENT}_connections.inizusammen. Dabei entspricht {CONTEXT} dem Context der aktuellen Applikation und projectone lautet. Details zur Konfiguration können dem Kapitel Konfiguration entnommen werden.
Der Inhalt der Konfiguration muss an die lokale Datenbank-Installation angepasst werden, genügt jedoch folgendem Schema:
[content-database]
DB.Host = "" ; Servername oder IP-Adresse der Datenbank
DB.User = "" ; Benutzer
DB.Pass = "" ; Passwort
DB.Name = "" ; Name der Datenbank
DB.Type = "MySQLx"
[DB.DebugMode = "true|false"
DB.Charset = "utf8"
DB.Collation = "utf8_general_ci"]Die vorliegende Webseite zeigt nun aus einer Textdatei oder Datenbank stammende dynamische Inhalten an. Ein Manko der Implementierung liegt noch darin, dass nicht abgefangen wird, ob ein Inhalt tatsächlich in der Datenbank existiert. Im Fall eines nicht vorhandenen Datenbank-Inhalts wird keine Fehlerseite ausgegeben, bei Verwendung der Datei-Variante ist dies bereits in der TagLib vorgesehen.
Darüber hinaus fehlt bei der in Kapitel 5.2 beschriebenen Vorgehensweise die Möglichkeit, eine Seite zu erstellen, zu pflegen und zu löschen. Diese Aufgabe kann im Moment lediglich mit einem Datenbank-Administrationstool wie PHPMyAdmin oder einem dafür erstelltes Tool erledigt werden.
Der Einfachheit wegen wurde in diesem Tutorial darauf verzichtet eine korrekte 3-Schicht-Implementierung aufzuzeigen, da dies den Schwierigkeitsgrad erheblich erhöht hätte. Fortgeschrittene Benutzer sollten jedoch die Datenbank-Kommunikation nicht direkt in einem Document-Controller vornehmen, sondern eine Business-Komponente eingeführen, die dem Controller ein "Inhalts-Domain-Objekt" liefert, das dieser dann anzeigt. Diese kümmert sich dann um die Bereitstellung einer Fehlerseite, sollte die vom Benutzer gewünschte Seite nicht existieren. Konsequenterweise greift die Business-Komponente auf eine Service-Komponente der Daten-Schicht zurück, die schließlich die Daten physikalisch aus der Datenbank bezieht. Innerhalb der Datenschicht kann dann Gebrauch vom ConectionManager gemacht werden um die relevanten Daten aus der MySQL-Datenbank zu laden. Weitere Anregungen bieten hier die Tutorials
Die in diesem Tutorial erstellten Dateien können unter tutorial_testwebsite.zip heruntergeladen werden. Nicht im Archiv enthalten sind die Quellcodes des Frameworks, da diese, wie bereits erwähnt, auf der Seite Downloads bezogen werden können.
Die Entwicklung des APF wird von JetBRAINS mit PHPStorm-Lizenzen unterstützt und wir sind überzeugt davon, dass PHPStorm die Qualität nachhaltig steigert. Benutzen auch Sie PHPStorm!
Proud to useIntelligent PHP IDE for coding, testing and debugging with pleasure