10.6 Ein Klient ohne JavaScript
Bernhard: Jetzt haben wir ziemlich alles, was wir brauchen, um die Anwendung fertigzustellen. Wir können die Dienste programmieren, ohne uns um die Kommunikation mit dem Klienten, die Verwaltung der Datenbankverbindung oder die Authentifizierung des Benutzers kümmern zu müssen. Wir können die Struktur, den Stil und das Verhalten der HTML-Seiten voneinander getrennt entwerfen. Und wir haben ein Framework, mit dem wir die HTML-Seiten über Ajax mit den Diensten kommunizieren lassen können.Aber trotzdem bin ich mit unserer Lösung nicht ganz zufrieden. Was ist mit den Benutzern, die kein JavaScript verwenden möchten? Was ist mit den Suchmaschinen, wie würden diese unsere Seiten indizieren können, wenn sie ohne JavaScript und Ajax einfach leer bleiben?Gregor: Du hast recht. Ajax ist eine mächtige Technologie, mit der man die Benutzerinteraktion mit einer Webanwendung viel attraktiver und angenehmer gestalten kann. Aber nicht alle wollen JavaScript verwenden, und das asynchrone Laden der Daten ist für die Suchmaschinen auch nicht besonders gut geeignet.Jetzt zeigt sich aber der Nutzen, den uns die Trennung der Anliegen, die Trennung der Fachlogik von der Darstellungslogik, gebracht hat. Wir können eine andere Variante der Darstellungslogik implementieren, die kein JavaScript braucht.
Was wir jetzt also brauchen, ist eine neue Implementierung der Darstellungslogik, die nicht in JavaScript im Browser, sondern auf dem Server in PHP implementiert wird.
Der Stil der HTML-Seiten ändert sich nicht, also können wir die bereits vorhandenen CSS-Dateien verwenden.
Die Struktur der HTML-Dateien ändert sich kaum – sie bleibt unverändert, bis auf die Skript-Elemente, die wir nicht brauchen. Wir könnten also die bereits vorhandenen HTML-Dateien als Vorlagen für die neue serverseitige Implementierung der Darstellungslogik verwenden.
Was wir allerdings wirklich neu implementieren müssen, ist die Anreicherung der HTML-Seite mit Daten, denn dies ist bisher in JavaScript-Dateien implementiert.
Bisher haben wir für das Füllen der HTML-Vorlagen die Bibliothek jQuery verwendet. Glücklicherweise wurde jQuery unter dem Namen phpQuery nach PHP portiert. [Sie können phpQuery von http://code.google.com/p/phpquery/ herunterladen. ]
Wir können also unser Skript aus kontakte.js ziemlich direkt nach PHP portieren.
Wir werden jetzt ein PHP-Skript erstellen, das
- die bereits existierenden HTML-Dateien verwendet,
- die bereits existierenden Dienste nutzt (allerdings werden diese direkt am Server aufgerufen),
- den bereits existierenden Dispatcher für die Erstellung der Exemplare der Dienste verwendet, um die vorhandene Funktionalität der Dependency Injection nutzen zu können, und
- statische HTML-Seiten produziert, mit denen Klienten ohne JavaScript die Kontaktdaten verwalten können.
Bevor wir mit diesem Skript anfangen, müssen wir allerdings unseren Dispatcher ein wenig anpassen.
Bisher wurde die Klasse in der Datei dispatcher.php implementiert, und diese enthielt neben der Klasse Dispatcher noch den Aufruf des Dispatchers. Damit wir die Klasse Dispatcher auch in anderen PHP-Skripten verwenden können, sollten wir sie in eine separate Datei auslagern, die außer der Deklaration der Klasse nichts anderes enthält. [Es ist sowieso eine gute Konvention, wenn man PHP-Klassen in separaten Dateien hält, die nach den Klassen benannt sind. In unserem Beispiel heißen die Dateien class.Klassenname.php – mit Ausnahme der Dienstklassen, die in Dateien mit dem Namen dienst.Klassenname.php programmiert werden. ]
Eine weitere Änderung besteht darin, dass der Dispatcher nicht den HTTP-Aufruf selbst behandeln kann. Wir wollen ja keine JSON-Struktur an den Klienten senden, sondern die HTML-Seite selbst erstellen. [Mit phpQuery könnten wir tatsächlich unsere Dienste über serverseitiges Ajax – also wirklich den Dispatcher, wie er bereits existiert, über HTTP – aufrufen. Allerdings wäre es nicht besonders effektiv, auf die eigenen Klassen über einen HTTP-Aufruf zuzugreifen. ] Wir werden den Dispatcher also nur zur Erstellung eines Exemplars des benötigten Dienstes brauchen. Folglich müssen wir die Sichtbarkeit der Methode dienstErstellen von privat auf öffentlich erhöhen.
Doch nach diesen kleinen Änderungen können wir sofort mit der Implementierung der serverseitigen Darstellungslogik anfangen. Da wir den Dienst Kontakte in die Datei dienst.Kontakte.php verschoben haben, können wir unser Skript jetzt einfach kontakte.php nennen.
<?php require_once('class.Dispatcher.php'); require_once('phpQuery/phpQuery.php'); $doc = phpQuery::newDocumentFileXHTML('kontakte.html'); // Wir wollen kein JavaScript an den Browser senden pq("script")->remove(); // kontakte.js nach PHP portiert class KontakteServerScript { private static $neuerEintrag = 0; public function kontaktAnzeigen($id, $kontakt) { $dl = pq("<dl/>"); foreach ($kontakt as $i => $eintraege) { $dl->append(pq("<dt/>")->text($eintraege->name . ':')); $eintrag = $eintraege->eintrag; if (!array_key_exists('id', $eintrag)) { foreach ($eintrag as $j => $eintragJ) { $dl->append( pq("<dd/>")->append( pq("<input/>") ->attr('name', 'bearbeitet[' . $eintragJ['id'] . ']') ->val($eintragJ['wert']) ) ); } $dl->append( pq("<dd/>")->append( pq("<input name='neu[" . $id . "][" . $eintraege->id . "][" . self::$neuerEintrag++ . "]' />"))); } else if (array_key_exists('id', $eintrag)) { $dl->append( pq("<dd/>")->append( pq("<input/>") ->attr('name', 'bearbeitet[' . $eintrag['id'] . ']') ->val($eintrag['wert']) ) ); } } return $dl; } public function kontakteAuflisten($data) { $kontakte = pq("<ul/>"); foreach ($data['daten'] as $id => $datenElement) { $kontakt = pq("<li/>"); $kontakte->append($kontakt); $kontakt->append( self::kontaktAnzeigen($id, $datenElement)); } pq("#kontakte")->append($kontakte); } } session_start(); $dispatcher = new Dispatcher(); $dienstKontakte = $dispatcher->dienstErstellen("Kontakte"); $data = $dienstKontakte->auflisten(); KontakteServerScript::kontakteAuflisten($data); print $doc; session_write_close(); ?>
Listing 10.16 Serverseitige Darstellung der Kontakte mit phpQuery
Im Gegensatz zu jQuery müssen wir phpQuery explizit sagen, auf welchem Dokument die Anfrage stattfinden soll. Wir erstellen das Dokument aus der gleichen Vorlage, wie wir sie in der Ajax-Version unserer Anwendung verwenden .
Da wir in dem fertigen HTML-Dokument kein JavaScript haben möchten, löschen wir einfach alle Skript-Elemente aus dem geladenen Dokument .
Das clientseitige Skript kontakte.js müssen wir nach PHP portieren. Es ist nicht schwierig, da phpQuery sich sehr stark an jQuery orientiert. Wir nutzen einfach statt der Funktion jQuery (beziehungsweise $) die Funktion pq und verwenden die PHP-Syntax .
Da wir den Dispatcher nur zum Erstellen der Dienste verwenden , müssen wir uns selbst um die Verwaltung der Session kümmern .
Die benötigte Operation des Dienstes rufen wir auch selbst auf , um das Ergebnis der Operation an das portierte Skript zu übergeben .
Zum Schluss müssen wir selbstverständlich das fertige Dokument ausgeben .
Das Ergebnis können Sie in Abbildung 10.4 sehen, die hier der Einfachheit halber noch einmal aufgeführt ist.
Abbildung 10.5 Der erste Screenshot mit ein wenig Stil
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.