Di 5 Sep 2006
Erstellung eines Webservice mit PHP unter Verwendung von XML-RPC
Posted by Oliver under Programmierung , Tutorials , PHPNo Comments
Mit diesem Tutorial wollen wir uns mal sozusagen dem Internet hinter dem Internet zuwenden, den Bereich, den man nicht zu sehen bekommt, der aber für den Bereich e-commerce mittlerweile von fundamentaler Bedeutung ist: Webservices.
Was ist das? Ein Webservice stellt Informationen, einen Service, zur Verfügung. Dies ist nicht unbedingt so spannend aber dieser Service agiert nicht direkt mit einem Menschen sondern wird normalerweise von einer Software angesprochen. Die Maschinen sprechen sozusagen automatisiert untereinander. Das hört sich auf jeden Fall schon einmal viel spannender an!
Zur weiteren Vertiefung der Theorie, sei unbedingt auf den Wikipedia-Artikel verwiesen. Insbesondere das Schaubild zur Funktionsweise sollte man sich vor Augen halten.
Wir wollen beispielhaft jetzt einen Beitrag für eine serviceorientierte Architektur (SOA) leisten.
Dazu nehmen wir PHP und XML-RPC. PHP sticht in dem Bereich der SOA nicht unbedingt als die Sprache der 1. Wahl hervor. Meist wird hier Java oder C# verwendet, die Mechanismen sind aber auch in PHP vorhanden. Zur Kommunikation benutzen wir XML-RPC.
XML-RPC bedeutet "XML-Remote-Procedure-Call" und erlaubt die Kommunikation, bzw. den Methodenaufruf, über Software auf verschiedenen Systemen, unter verschiedenen Umgebungen zu kommunizieren. Der gemeinsame Nenner ist ein TCP/IP-basiertes Netzwerk. Die Methodik ist in vielen Programmiersprachen implementiert. Das bedeutet, dass der Anbieter eines Service nicht in der gleichen Sprache erstellt sein muss wie der Konsument.
Den gemeinsamen Nenner des TCP/IP-basierten Netzwerk, muss man noch etwas einschränken: Der Aufruf der entfernten Methoden erfolgt über HTTP. Die Rückgabe der Methode ist dann in intern XML verpackt, wobei dort folgenden Datentypen vorhanden sein können:
- int, double, boolean, String, DateTime-iso8601, Base64-String (ByteStrom)
Wenn man genauere Ergebnisse benötigt, kann man die Resultate auch in eine Struktur (struct) packen. Ein Struct ist ähnlich einem Hash. Er besitzt einen Key (Typ String) und ein Value (beliebiger oben genannter Datentyp).
Soweit zur Theorie… Bevor die Praxis folgt, sollte man sich folgendes Bild am besten ausdrucken und neben die Tastatur legen. Das Schaubild verdeutlicht die generelle Funktionsweise von XML-RPC (spezialisiert) unter PHP und es wird immer wieder auf das Schaubild zur Erklärung des Code verwiesen.
Bild: xmlRPC.png
Zur Funktionsweise müssen wir noch sicherstellen, dass wir das PEAR-Package XML_RPC benutzen können.
Beispiel: Wir implementieren eine Suchfunktion für Mitarbeiter.
Um das Beispiel nicht zu komplex werden zu lassen, kann nur nach dem Ort eines Mitarbeiters gesucht werden.
1. Schritt: Eine Mitarbeiter-Datenbank aufbauen.
Wir implementieren eine rudimentäre Mitarbeiter-Datenbank in MySQL.
Datenbank-Skript mitarbeiter.sql.txt
2. Schritt: Aufbau einer Abfragemaske
Die Abfragemaske wird sehr minimal aufgebaut. Sie stellt nur eine einfache Eingabemöglichkeit dar, einen Ortsnamen einzugeben. Dieser Ortsname wird an den XML-RPC Client übergeben (siehe Bild).
Datei: gui.php
3. Entgegenname der Suchanfrage durch den XML-RPC Client
Zuallerst müssen wir im Client durch einen include sicherstellen, dass wir das PEAR-Package eingebunden haben. Danach packen wir den empfangenen Wert in die Variable $ort.
Jetzt sollten wir uns das Bild wieder zu Hilfe nehmen. Die Variable $ort wird in ein XML_RPC_Value verpackt ($para1) mit der entsprechenden Typ-Angabe (string).
Anschließend muss dieses XML_RPC_Value in ein PHP-Array gepackt werden ($parameterArray) , welches in eine XML_RPC_Message gepackt wird ($nachricht). Der erste Parameter für XML_RPC_Message ist hierbei der Name, der externen Funktion. D.h. der Name der nach außen vom Service her sichtbar ist. Intern kann dieser Name komplett anders heißen. Dazu aber später…
Wir benötigen jetzt eine Instanz vom Typ XML_RPC_Client ($xmlrpc) und übergeben hier den URL-Pfad unter
der der Service erreichbar ist, den Host und den Port. Über diese Instanz, können wir jetzt unsere Nachricht ($nachricht) an den Service verschicken und erhalten das Ergebnis in der Variable $response. In der folgenden If-Bedingung wird das Ergebnis dann entpackt und kann genutzt werden. Wir entpacken hier in die Variable $ergebnis und übergeben das Ergebnis als Get-Parameter an die gui.php zurück.
Datei: client.php
4. Der Service antwortet
Der Service muss als Erstes das PEAR Server Package für XML-RPC inkludieren. Im nächsten Schritt wird eine Instanz vom Typ XML_RPC_Server gebildet. Dieser Instanz wird ein mehrdimensionales Array übergeben. In diesem Array ist ein Array pro Funktion enthalten welches folgende Angaben hat:
Name der Servicefunktion für extern (holeMitarbeiter) als Key, dann bis zu drei Werte in einem Array und zwar der interne Funktionsname und optional docstring und signature. docstring enthält eine Beschreibung, signature gibt den Rückgabewert an und den Typ der zu übergebenden Parameter.
Hier ist also extern der Funktionsname "holeMitarbeiter" sichtbar, der intern auf die Funktion "ichHole" weiterverweist.
In ichHole wird der Übergabeparameter weiterverarbeitet. Die Variable heißt hier $hasen, der Name spielt absolut keine Rolle. in $hasen ist der vom Client verpackte XML_RPC_Value, der in ein PHP-Array gesteckt wurde. Dieser wird hier wieder entpackt und steht uns dann als Variable $ort für die SQL-Abfrage zur Verfügung.
Nachdem die SQL-Abfrage durchgeführt wurde, packen wir die einzelnen Werte in XML_RPC_Values, diese wiederum in ein PHP-Array, welches ebenfalls in ein XML_RPC_Value vom Typ "Struct" gepackt wird ($RPC_ergebnis). $RPC_Ergebnis wird in eine XML_RPC_Response gepackt und ist der Rückgabewert der Funktion.
Datei: server.php
Das wars soweit! Ich hoffe, das Ganze war soweit einigermaßen verständlich und noch nachvollziehbar. Verwiesen werden sollte noch auf die XML_RPC Dokumentation auf der PEAR-Seite: http://pear.php.net/package/XML_RPC/docs/latest/