![]() |
|
URL dieses Artikels:
zu Ausgabe:
1.2005
From Babylon back to Babylon
Web Services mit XML-RPC
von Daniel Koch
Für viele Anwendungen ist SOAP einfach zu mächtig. Daher greifen Entwickler gerne auf XML-RPC zurück. Dieser Artikel zeigt die Unterschiede und Gemeinsamkeiten beider Ansätze und liefert einen Ausblick auf die Verwendung von XML-RPC in PHP. Denn Programmierer müssen längst nicht mehr nur auf PHP-eigene XML-RPC-Funktionen zurückgreifen, sondern können das PEAR-Packet XML_RPC verwenden. Außerdem liefert der Artikel einen Ausblick auf die SOAP-Extension, die in PHP 5 integriert wurde.
XML-RPC: SOAP light SOAP kann genauso wie XML-RPC zum entfernten Prozeduraufruf verwendet werden, was einen Vergleich beider Ansätze legitimiert. Von einigen Entwicklern wird XML-RPC zwar immer noch als eine Light-Version von SOAP gesehen, das trifft es allerdings nicht ganz. Denn für viele Anwendungen ist XML-RPC nicht nur eine Alternative zu SOAP, sondern eindeutig die bessere Wahl. Bevor die Unterschiede zwischen SOAP und XML-RPC gezeigt werden, werfen wir einen Blick auf die Gemeinsamkeiten. Beide Protokolle ermöglichen den Aufruf von entfernten Methoden über das Internet, sind plattformunabhängig und können als Transportprotokoll HTTP verwenden. So weit die Gemeinsamkeiten. Wie die folgende Auflistung beweist, überwiegen die Unterschiede.
Es wird deutlich, dass SOAP mehr Funktionen und Features bietet. Nur ist dieser enorme Funktionsumfang eben nicht immer nötig. Wann Sie welches Protokoll einsetzen, hängt ausschließlich von der Anwendung ab. Sind Schnelligkeit und Einfachheit gefragt, ist XML-RPC die richtige Wahl. Wenn komplexere Datentypen und Nachrichtenstrukturen gefordert sind, sollte SOAP eingesetzt werden. Fehlerbehandlung Wenn bei der Serverantwort ein Fehler auftritt, kann er mit einem fault-Element übergeben werden. Dieses besitzt wiederum ein <value>-Tag, in dem ein <struct>-Element enthalten ist. Dieses <struct>-Element besitzt wiederum zwei <member>-Tags. Die beiden <member>-Namen sind faultCode mit einer Fehlernummer und faultstring, das einen Fehlertext als String enthält. <methodResponse>Unterstützte Datentypen Bei XML-RPC muss die Antwort eines Methodenaufrufs genau einen Antwortwert enthalten. Dabei wird zwischen einfachen und zusammengesetzten Datentypen unterschieden. Jedes Datenelement wird durch ein <value>-Tag eingeschlossen. Die folgende Tabelle enthält alle einfachen (Grund)-Datentypen. Wurde kein Datentyp angegeben, wird der Wert als String (<string>) interpretiert (s. Tabelle 1). In XML-RPC können die einfachen Datentypen zu komplexen Datenstrukturen kombiniert werden (s. Tabelle 2). XML-RPC in PHP Auch in PHP 5 ist die XML-RPC-Extension nicht standardmäßig installiert. Nachholen lässt sich das mit -with-xmlrpc. Die XML-RPC-Extension liefert zahlreiche Funktionen, mit denen sich ganz einfach Server erzeugen bzw. zerstören und Clients implementieren lassen. Bei dieser Extension handelt es sich um eine Kopie der XML-RPC EPI-Extension, die unter [1] heruntergeladen werden kann. Einen Überblick über alle PHP-Funktionen von XML-RPC erhalten Sie unter [2]. Dort werden alle Funktionen vorgestellt. Einen ersten Eindruck sollen Ihnen die folgenden Beispiele vermitteln. XML-RPC benötigt einen Server und einen Client. Ein ausführlich dokumentiertes Beispiel finden Sie auf der beiliegenden Heft-CD. Um einen Server zu erzeugen, wird die Funktion xmlrpc_server_create() verwendet. Sie liefert eine Kennung zurück, anhand derer der Server identifiziert werden kann. Wenn der Server nicht gestartet werden kann, liefert sie FALSE. Um einen Server zu zerstören, wird die xmlrpc_server_destroy()-Funktion verwendet. $server = xmlrpc_server_create(); Das Beispiel erzeugt einen Server und zerstört ihn wieder. Wenn Sie nun eine PHP-Funktion haben, auf die ein Client zugreifen soll, müssen Sie die Funktion beim Server registrieren. Von da an kennt der Server die Funktion und sie kann von ihm angeboten werden. Dafür steht die Funktion xmlrpc_server_register_method() zur Verfügung. War die Registrierung erfolgreich, wird TRUE, anderenfalls FALSE zurückgegeben. Als erster Parameter wird die Kennung des erzeugten Servers und als zweiter Parameter der Name erwartet, über den die Funktion über XML-RPC erreichbar ist. Als letzten Parameter geben Sie den tatsächlichen Funktionsnamen an. Xmlrpc_server_register_method($server, "public.myMethod", "myFunction"); Durch das gezeigte Beispiel wird die Funktion myFunction registriert, auf die dann mittels myMethod zugegriffen werden kann. Die XML-RPC-Extension erlaubt es zusätzlich, dass Sie sich nicht selbst um XML-Prozesse kümmern müssen. Das erledigt die Funktion xmlrpc_server_call_method(). mixed xmlrpc_server_call_method ( server_kennung, string xml, mixed user_data [, array output_options]) Der Funktion wird zunächst wieder die Serverkennung übergeben. Anschließend folgt der in XML kodierte Client-Request. Als dritter Parameter schließen sich zusätzliche Daten an, an die PHP-Funktionen übermittelt werden können. Den vierten Parameter kann ein Array bilden, über das die Ausgabeoptionen genauer spezifiziert werden können. Mögliche Werte sind output_type (xml, php), escaping (non-ascii, non-print, markup, cdata), encoding (iso-8859-1 etc.), verbosity (pretty, newlines_only, no_white_space) und version (auto, xmlrpc, soap 1.1). Als Rückgabewert wird die Rückgabe der internen PHP-Funktion, die vom Server aufgerufen wird, geliefert. In XML-RPC gibt es die beiden Datentypen base64 und datetime. Die gibt es in PHP allerdings nicht. Dafür stellt PHP aber zwei Funktionen bereit, mit denen man Datentypen setzen und ermitteln kann. Mit der Funktion xmlrpc_set_type() kann der Datentyp explizit gesetzt werden. Im Erfolgsfall liefert die Funktion TRUE, andernfalls FALSE. Als erster Parameter wird eine Stringvariable erwartet, die per Referenz übergeben wird. Als zweiter Parameter wird ein in XML-RPC zulässiger Datentyp erwartet. Allerdings macht die Verwendung dieser Funktion nur im Zusammenhang mit datetime und base64 Sinn. Die Funktion xmlrpc_get_type() ermittelt den XML-RPC-Wert. Dieser Funktion wird eine Variable übergeben. Als Rückgabewert wird ein String geliefert, der zeigt, um welchen XML-RPC-Wert es sich handelt. $ausgabe = "news" Der Rückgabewert kann einer der zuvor genannten Datentypen sein. Um von einem Client auf einen Server zuzugreifen, muss ein XML-RPC-konformes XML-Dokument erzeugt werden. Hierin müssen Parameter und Methodennamen enthalten sein, die dann an den Server gesendet werden. Im nächsten Schritt wird dann die Serverantwort verarbeitet. Prinzipiell handelt es sich bei dem Methodennamen um eine einfache Zeichenkette. Wenn aber beispielsweise einem Methodennamen Parameter in Form einer PHP-Variablen übergeben werden sollen, ist das schon schwieriger. Hierfür hält die PHP-Extension aber eigene Funktionen bereit. Mit xmlrpc_encode() können Daten serialisiert bzw. kodiert werden. Als Parameter erwartet die Funktion den zu kodierenden PHP-Wert. Die Funktion liefert XML oder FALSE zurück. Um Werte zu deserialisieren, übergeben Sie den XML-Wert der Funktion xmlrpc_decode() und erhalten den PHP-Wert zurück. Um Anfragen zu verarbeiten, stehen die beiden Funktionen xmlrpc_encode_request() und xmlrpc_decode_request() zur Verfügung. Der Funktion xmlrpc_encode_request() wird als erster Parameter die XML-RPC-Methode, die beim Server aufgerufen werden soll, als String übergeben. Als zweiter Parameter kann ein skalarer Wert oder ein Array angegeben werden. Über den dritten optionalen Parameter kann die Ausgabeoption bestimmt werden. Hierbei sind die zuvor genannten Werte möglich. Als Rückgabewert liefert die Funktion ein XML-RPC-konformes XML-Dokument oder FALSE. Um die Daten wieder in PHP-Werte zu dekodieren, wird die Funktion xmlrpc_decode_request() verwendet. Als erster Parameter wird das XML-Dokument angegeben. Über den zweiten Parameter wird der Methodenname zurückgegeben. Als dritter Parameter kann noch der verwendete Zeichensatz (Standard: iso-8859-1) gesetzt werden. Der Rückgabewert ist ein PHP-Wert oder FALSE. Seit einiger Zeit existiert auch ein PEAR-Package für XML-RPC. Das Paket XML_RPC kann unter [3] heruntergeladen werden. Eine wunderbare Einführung zu XML_RPC ist unter [4] verfügbar. Die SOAP-Erweiterung von PHP 5 Mit PHP 5 wurde auch eine neue SOAP-Erweiterung entwickelt. Eine Einführung in dieses Thema gibt es unter [5]. Dort finden Sie auch ein ausgezeichnet dokumentiertes Beispiel. Gegenüber XML-RPC wurden in SOAP einige Schwachstellen ausgebessert. So können unter SOAP u.a. die Formate und Datentypen über XML-Schemata definiert werden. Hierüber kann auch beschrieben werden, welche Funktionen bereitgestellt werden sollen. Dafür ist die Web Service Description Language (WSDL) verantwortlich. Die WSDL-Spezifikation finden Sie unter [6]. Um die SOAP-Extension unter Windows einzusetzen, muss der Schalter extension=php_soap.dll in der php.ini aktiviert werden. Unter Linux müssen Sie PHP mit SOAP kompilieren. Zend stellt auf [7] ausführliche Beispiele vor. Wir wollen uns daher hier auf ein ganz einfaches konzentrieren, das aber trotzdem die Arbeitsweise von SOAP demonstriert. Den meisten von Ihnen dürfte BabelFish ein Begriff sein. Es handelt sich hierbei um einen Translator, mit dem einzelne Wörter, aber auch ganze Webseiten übersetzt werden können. Wie einfach sich hierfür ein Client programmieren lässt, der einen übergebenen deutschen String ins Englische übersetzt, wird nachfolgend beschrieben. Die WSDL-Datei für BabelFish finden Sie auf [8]. Unter [9] wird diese Datei ausführlichst beschrieben. Konzentrieren wir uns hier auf das PHP-Skript, durch das wir Hallo, Welt! via SOAP in Hello, World! übersetzen können. <?php In der WSDL-Datei steht, welche Funktionen das $client-Objekt hat. Im nächsten Schritt muss die Anfrage gesendet und der Rückgabewert ausgegeben werden. <?php Dabei gibt der erste Parameter die beteiligten Sprachen an. Durch de_en geben wir also an, dass vom Deutschen ins Englische übersetzt werden soll. Dieser Parameter ist in der WSDL-Datei mit translationmode beschrieben. Als zweiter Parameter wird der zu übersetzende String angegeben, der in der WSDL-Datei sourcedata heißt. Es ist also einfach, einen Client zu erstellen. Allerdings hatte dieses Beispiel einen entscheidenden Nachteil: Die WSDL-Datei wird durch das Skript vollständig vom Server geladen, was zu Lasten der Performance geht. Auf den Zend-Seiten wird ausführlich beschrieben, wie sich dieses Problem vermeiden lässt. Dort gibt es auch weiterführende Beispiele. Dort wird u.a. gezeigt, wie Sie einen eigenen Server erstellen können. Alles in allem ist die SOAP-Extension von PHP 5 gelungen. Die entsprechenden Funktionen gibt es unter [10]. Positiv zu erwähnen ist noch die Möglichkeit zur Fehlerbehandlung über die Funktion is_soap_fault(). Grenzen von XML-RPC Der Artikel hat es gezeigt: XML-RPC ist ein interessantes Protokoll, mit dem man allerdings schnell an seine Grenzen gelangt. Die Probleme beginnen schon mit der fehlenden Schnittstellenbeschreibung, die es zum Beispiel bei CORBA IDL gibt. Dadurch können Proxies für den Server-Zugriff nicht automatisch erzeugt werden. Ebenso ist dem automatischen Serialisieren enge Grenzen gesetzt. Bei vielen Implementierungen müssen Objekte manuell aus Struts und Arrays übersetzt werden. Als Fazit bleibt: Wer einen schnellen und unkomplizierten Web Service erstellen möchte, der sollte auf XML-RPC zurückgreifen. Geht es um anspruchsvollere Projekte im E-Business, sollte nach wie vor auf SOAP gesetzt werden. Daniel Koch arbeitet als freiberuflicher Programmierer und Autor in Hamburg und Berlin. Er hat mehrere Bücher rund um die Themen Programmierung und Software veröffentlicht. Sie erreichen ihn unter dk@medienwerke.de. Links und Literatur [1] http://xmlrpc-epi.sourceforge.net/main.php?t=php_about [2] http://de.php.net/manual/en/ref.xmlrpc.php [3] http://pear.php.net [4] http://codewalkers.com/tutorialpdfs/tutorial61.pdf [5] http://www.zend.com/php5/articles/php5-SOAP.php [6] http://www.w3.org/TR/2001/NOTE-wsdl-20010315 [7] http://www.zend.com/php5/articles/php5-SOAP.php [8] http://www.xmethods.net/sd/2001/BabelFishService.wsdl [9] http://www.asnative.de/docs/WSDLDoc_Babelfish.html [10] http://www.php.net/manual/en/ref.soap.php |
||
|