Web Services per JavaScript einbinden: SOAP mit PHP5 und JavaScript
Soap (Simple Object Access Protocol) ist ein einfaches XML-basiertes Protokoll, mit dem Anwendungen Informationen über HTTP austauschen können. Das Interessante an Soap ist, dass Objekte und deren sichtbare Eigenschaften sprachübergreifend über das WWW übertragen und individuell aufbereitet werden können. Ein bekannter Anbieter einer Soap-Schnittstelle ist Amazon. Mit Amazons Schnittstelle kann man beispielsweise Produkte aus Amazons Angebot auf der eigenen Homepage platzieren. Darüber hinaus existiert eine Vielzahl weiterer Verwendungsmöglichkeiten (nicht nur im Bereich der Content-Syndication), die dem bloßen Inkludieren von fremden Seiten oder RSS-Feeds haushoch überlegen sind.
PHP5 bringt eine eigene Extension mit, die beliebige Soap-Server und -Clients erstellen kann. Es gibt zwar auch einige separate Soap-Implementationen für PHP (z. B. von PEAR), jedoch sind diese meist in PHP verfasst und somit in Sachen Performance einer in C geschriebenen PHP-eigenen Extension unterlegen.
Startpaket
Um dieses Tutorial am eigenen Rechner nachvollziehen zu können, empfiehlt sich das „PHP5-Rundum-Sorglos-Paket“ XAMPP. Damit kann man sich unter Windows und Linux im Handumdrehen eine PHP5-Testumgebung schaffen und die hier bereitgestellten Code-Beispiele ausprobieren. Nach der Installation von XAMPP muss die Soap-Extension in der Datei „php.ini“ aktiviert werden. Falls Sie kein XAMPP verwenden und nicht wissen, welche „php.ini“ gerade vom Webserver genutzt wird, erstellen Sie eine PHP-Datei mit dem Inhalt „<? phpinfo(); ?>“, kopieren diese in Ihr Document-Root-Verzeichnis und öffnen die Datei im Browser. Falls Sie XAMPP verwenden, können Sie im XAMPP-Navigationsmenü den Punkt „phpinfo()“ auswählen. Dort steht in der Zeile „Configuration File (php.ini) Path“ der Pfad zur „php.ini“, die Sie anpassen müssen.
Suchen Sie in der „php.ini“ nach der Zeile „;extension=php_soap.dll“, entfernen Sie das Semikolon, speichern Sie ab und starten Sie den Webserver neu. Zum Testen des Clients benötigen Sie den Firefox-Browser. Zum Erstellen und Bearbeiten der Beispiele genügt ein einfacher ASCII-Text-Editor.
Der Soap-Server
Beim Erstellen des Soap-Servers mit PHP5 besteht die Möglichkeit, eine Definitionsdatei nach der Spezifikation WSDL (Web Services Description Language) zu nutzen. WSDL ist eine XML-basierte Beschreibungssprache, um Funktions- bzw. Methodenaufrufe und Datentypen zu definieren. Für den Soap-Server ist eine WSDL-Datei nicht zwingend notwendig, sollte aber bei steigender Komplexität der Web Services auf jeden Fall eingesetzt werden. Nötig wird eine WSDL-Datei spätestens dann, wenn die Datenübertragung mit SSL verschlüsselt werden soll, denn diese Angabe muss explizit in der WSDL-Datei vorhanden sein. Darüber hinaus gibt es Tools, die aus WSDL-Dateien Programmcode erzeugen können – für das Rapid-Prototyping eine äußerst nützliche Hilfe. Ein gutes Tool, um WSDL-Dateien „On-the-fly“ zu erzeugen, ist der SOA-Editor von Cape Clear [1]. Der Soap-Server in diesem Tutorial kommt ohne eine WSDL-Datei aus. Um den Umfang des Artikels nicht zu sprengen, haben wir alle längeren Quelltext-Blöcke auf t3n-magazin.de hinterlegt. Sie erreichen diese und alle hier abgedruckten Code-Blöcke über den Softlink am Ende des Artikels.
Kopieren Sie die Dateien „soap_server.php“ und „MySoapClass.php“ in Ihr Document-Root-Verzeichnis. In der Datei „soap_server.php“ wird festgelegt, dass keine WSDL-Datei verwendet wird und dass die Funktionen der Klasse „MySoapClass“ dem Client zur Verfügung stehen sollen. Die Klasse „MySoapClass“ in „MySoapClass.php“ stellt den eigentlichen Service dar. Hier werden dem Client die Funktionen „MySoapClass::getAttributesClass()“ und „MySoapClass::putSomethingToServer($something)“ bereitgestellt. Erstere Funktion übergibt dem Client eine Instanz der Klasse „MyAttributesClass“. Alle öffentlichen Eigenschaften werden dann vom Client weiterbehandelt. Die zweite Funktion zeigt, dass einer Soap-Funktion auch Parameter übergeben werden können.
Der Soap-Client
Um den Rahmen dieses Tutorials überschaubar zu halten, finden Sie über den Softlink eine vorgefertigte und einfach zu verwendende JavaScript-Klasse namens „BlasterSoapClient.js“, die zur Steuerung des Soap-Clients dient. Kopieren Sie diese Datei in ein beliebiges Verzeichnis auf Ihren Webserver. Kopieren Sie anschließend die Datei „soap_client_getattrib.html“ in denselben Ordner.
Öffnen Sie nun die Datei „soap_client_getattrib.html“ mit dem Firefox-Browser über „Datei öffnen“. Sie werden darum gebeten, Ihr Einverständnis für die Ausführung des Soap-Aufrufs zu erteilen. Warten Sie ein paar Sekunden und klicken Sie dann auf „Allow“. Nun sollten Sie folgende Ausgabe erhalten:
[object SOAPPropertyBag] Empfangen: Inhalt 1 Inhalt 2 Inhalt 3 Inhalt 4 Inhalt 5
Listing 1
Hätten Sie die Datei nicht über das Browser-Menü „Datei öffnen“, sondern über „http://localhost/…“ aufgerufen, wären die Sicherheitseinstellungen von Mozilla Firefox auf den Plan gerufen worden und der Client hätte keine Antwort vom Soap-Server erhalten. Das ist vollkommen in Ordnung, denn ein Webserver soll dem Client keinen Soap-Code unterjubeln können, der dann beliebige Daten nachlädt. Der Aufruf „BlasterSoapClient.invoke(‚getAttributesClass‘,new Array(0));“ bewirkt, dass der Client (also der Browser) wartet, bis vom Server eine Rückmeldung kommt. Daher ist die Verwendung von „invoke“ auch nur dann zu empfehlen, wenn nicht viele Daten transportiert werden sollen (z. B. bei Login-Prozeduren). Für größere Datenmengen empfiehlt sich der Aufruf der Funktion „BlasterSoapClient.asyncInvoke(funktion,argumente, callbackfunktion)“. Der asynchrone Aufruf bewirkt, dass das Skript normal weiterläuft. Zur Behandlung der empfangenen Daten wird jedoch eine Callback-Funktion benötigt, die dem Funktionsaufruf mitgegeben wird. Da bei JavaScript Funktionen bereits Objekte sind, können Sie die Funktion direkt als Parameter an „BlasterSoapClient.asyncInvoke“ übergeben.
Um das Beispiel des asynchronen Übertragens von Daten mit Soap nachvollziehen zu können, kopieren Sie die Datei „soap_client_getattrib_async.html“ in den Ordner, in dem sich bereits die Datei „soap_client_getattrib.html“ befindet.
Wenn Sie nun das Beispiel im Browser öffnen, sehen Sie, dass es im Grunde nur eine Änderung gab. Statt das Ergebnis des Aufrufs der Soap-Funktion direkt in die Variable „attributesClass“ zu speichern, geschieht dies beim asynchronen Aufruf erst in der Callback-Funktion. Bei größeren Datenmengen könnte man mit wenig Aufwand einen Fortschrittsbalken einbauen, damit der Benutzer sieht, dass im Hintergrund etwas passiert. Der Einfachheit halber wird in diesem Tutorial die synchrone Variante genutzt.
Im folgenden Schritt soll auf dem Soap-Server die Funktion „MySoapClass::putSomethingToServer($something)“ ausgeführt und dieser ein Parameter übergeben werden. Kopieren Sie dazu die Datei „soap_client_putargs.html“ in den Ordner, in dem sich bereits die Datei „BlasterSoapClient.js“ befindet.
Der Parameter mit dem Inhalt „Irgendein String“ wurde nun an „MySoapClass::putSomethingToServer($something)“ übergeben und ein SoapFault-Objekt mit dem Inhalt der Nachricht wurde an den Client zurückgeschickt. SoapFaults sind wichtig, um dem Client Fehler mitzuteilen, die auf dem Server passiert sind (z. B. Eingabefehler, Exceptions etc.). Dadurch muss der Client nicht auf die Antwort warten. Außerdem kann man sich Tests sparen, in denen geprüft wird, ob alle Werte auch wirklich angenommen wurden.
Fazit
Einen zentralen Web-Service-Server vorausgesetzt, lassen sich auch mit JavaScript anspruchsvolle, Web-Service-basierte Applikationen umsetzen. Der direkte Zugriff per SOAP auf den Server erspart hierbei der JavaScript-Anwendung den Umweg über ein serverseitiges PHP-Skript, das dann wieder per XML oder JSON die Daten zum Client vermitteln müsste.