Ich will euch mit diesem Tutorial zeigen, wie einfach es doch ist mit SOAP bestimmte Informationen zu bekommen. Durch PHP5 wurde es ziemlich erleichtert. Ich werde mit euch einen Clienten erstellen, der auf einen SOAP-Server zugreift und seine Daten sendet und wieder welche empfängt. Dazu will ich euch auch ein bekanntes Beispiel zeigen. Jeder von euch hat bestimmt schonmal von BabelFish gehört, dem Übersetzungstool von Altavista. Dies werden wir mit SOAP ansprechen und somit unseren eigenen kleinen Übersetzer bauen.
Ausserdem werde ich euch erklären, wie ihr euren eigenen SOAP-Server der Aussenwelt zur Verfügung stellt unter der Verwendung von WSDL-Dateien. Erklärung gibt es dazu noch später.
2. Was ist SOAP?
Ausgesprochen heisst es "Simple Object Access Protocol" und meiner Meinung nach kann man mit SOAP einfache Kommunikation zwischen Servern durchführen. Von einer simplen Abfrage von Daten bis zur Fernsteuerung des Computers ist alles möglich.
Die Daten, welche SOAP erwartet und zurückgibt, sind in XML geschrieben. Aber wenn man die Fkt. von PHP5 benutzt sollte dies eigentlich nicht interessieren.
3. Hinweis für dieses Tutorial
Vorraussetzung für dieses Tutorial ist, dass man PHP5 installiert hat.
Für Linux-Nutzer: Ihr müsst SOAP mit kompiliert haben. Aber leider bin ich kein Linux-Nutzer, um genauere Informationen zu geben.
Für Windows-Nutzer: Man muss eigentlich nur noch in der php.ini diese SOAP-Extension aktivieren ( "extension=php_soap.dll")
Nun hat man alles, was man dafür braucht, um mit SOAP loszulegen.
4. Das erste Skript
Ich versuche euch nun anhand von BabelFish zu erklären, wie man leicht einen Clienten schreibt. Es gibt Dateien, in der zB. definiert ist, welche Fkt. über SOAP ansprechbar sind. Diese Dateien tragen meist die Endung WSDL. Sie benutzen die Scriptsprache XML und definieren alles, um es euch zu erleichtern, diesen Service zu benutzen. Die WSDL-Datei für BabelFish findet ihr unter http://www.xmethods.net/sd/2001/BabelFishService.wsdl
Am Anfang sieht es ein wenig kryptisch aus, aber die Erklärung kommt später, wenn wir unseren eigenen SOAP-Server basteln.
Fangen wir nun an. Wir wollen ein kleines Skript schreiben, welches "Hallo Welt" in das Englische übersetzt.
Das erste was wir machen müssen ist ein SoapClient-Objekt zu erstellen
PHP-Code:
<?php
$client = new SoapClient('http://www.xmethods.net/sd/2001/BabelFishService.wsdl');
?>
Nun müssen wir nur noch die Anfrage senden und den Rückgabewert, unseren englischen Text, ausgeben.
PHP-Code:
<?php
$result = $client->BabelFish('de_en', 'Hallo Welt');
echo $result;
?>
Somit haben wir schon unser erstes SOAP-Skript geschrieben. Ist doch garnicht mal so schwer

5. Das zweite Skript
Der Nachteil des ersten Skriptes ist, dass SOAP diese WSDL-Datei komplett vom Server lädt und das bei großen Datenmengen ziemlich in die Performance geht. Man kann dies auch anders bewerkstelligen.
Ich zeige euch das wieder an dem Beispiel von BabelFish.
Als erstes müssen wir wieder ein SoapClient-Objekt erstellen. Diesmal aber nicht über die Definitionsdatei, sondern direkt an dem Skript, was uns die Übersetzung liefern soll.
PHP-Code:
<?php
$client = new SoapClient(NULL,
array(
"location" => "http://services.xmethods.net/perl/soaplite.cgi", //Dieses Skript übersetzt uns unseren Text
"uri" => "urn:xmethodsBabelFish", //Ein Namespace
"style" => SOAP_RPC, //Art der Handhabung, hier Methodenaufruf (Remote Procedure Call)
"use" => SOAP_ENCODED //Verschlüsselte Übertragung
));
?>
Nun wollen wir ja auch noch unseren Text senden und das Übersetzte empfangen.
PHP-Code:
<?php
$parameters = array( // Ein Array mit den Paramtern für die Funktion 'BabelFish'
new SoapParam('de_en', 'translationmode'), // erster Parameter SoapParam('Wert', 'Variablenname')
new SoapParam('Hallo Welt', 'sourcedata')); //zweiter Paramter
$result = $client->__call(
"BabelFish", //Die Methode, die ihr aufrufen wollt
$parameters, //Paramter, die die Funktion verlangt
array( //Optionen für SOAP
"uri" => "urn:xmethodsBabelFish", //wieder dieses Namespace
"soapaction" => "urn:xmethodsBabelFish#BabelFish" //keine Ahnung muss aber rein
));
echo $result;
?>
6. Der erste Server
Nun wollen vielleicht paar von euch auch einen SOAP-Server aufbauen, weil man ja auch mit SOAP remoting betreiben kann. Um einen Server zu erstellen, müsst ihr einfach ein SoapServer-Objekt erstellen (wer hätte das gedacht
)Wir wollen am Anfang ein kleinen Server erstellen, der eine Fkt. hat. Diese addiert einfach nur die 2 Paramter.
server.php:
PHP-Code:
<?php
function addiere($sum1, $sum2) {
return $sum1 + $sum2;
}
$server = new SoapServer(NULL,
array('uri' => "http://{uri}/")); //{uri} müsst ihr ersetzen mit den pfad
$server->addFunction('addiere'); //Funktion zum Server hinzufügen
$server->handle(); //Hier wird die Abfrage abgearbeitet
?>
Der Client sieht nun folgendermassen aus.
client.php
PHP-Code:
<?php
$client = new SoapClient(NULL,
array(
"location" => "http://{url}/server2.php", //{url} müsst ihr durch den Pfad ersetzen
"uri" => "urn:xmethodsTestServer",
"style" => SOAP_RPC,
"use" => SOAP_ENCODED
));
$parameters = array(
new SoapParam('10', 'sum1'),
new SoapParam('20', 'sum2'));
$result = $client->__call(
"addiere",
$parameters,
array(
"uri" => "urn:xmethodsTestServer",
"soapaction" => "urn:xmethodsTestServer#addiere" //irgendein Platzhalter
));
echo $result;
?>

7. Aufbau einer WSDL-Datei
Nun wollt ihr aber bestimmt nicht immer soviel eingeben, nur um 2 Zahlen zu addieren. Deswegen widmen wir uns nun der Definitionsdatei. Am Anfang wird es jedem ein wenig verwirrend vorkommen, aber ich hoffe, dass ihr nach dieser Erklärung auch die Definitionsdatei von BabelFish versteht.
Die WSDL-Datei von BabelFish fängt damit an.
BabelFishService.wsdl:
Code :
1 2 3 4 5 6 | <?xml version="1.0"?>
<definitions name="BabelFishService" //Name der Definition
xmlns:tns="http://www.xmethods.net/sd/BabelFishService.wsdl" //der Pfad der WSDL-Datei
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/"> |
Nun kommen wir zu einem wichtigen Teil dieser Datei.
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 | <message name="BabelFishRequest">
<part name="translationmode" type="xsd:string"/>
<part name="sourcedata" type="xsd:string"/>
</message>
<message name="BabelFishResponse">
<part name="return" type="xsd:string"/>
</message>
<portType name="BabelFishPortType">
<operation name="BabelFish">
<input message="tns:BabelFishRequest" />
<output message="tns:BabelFishResponse" />
</operation>
</portType> |
Die Zeile mit dem "part" bestimmt die Variablen, die übergeben werden.
Code :
1 2 3 4 | <message name="BabelFishRequest">
<part name="translationmode" type="xsd:string"/>
<part name="sourcedata" type="xsd:string"/>
</message> |
Code :
1 2 3 | <message name="BabelFishResponse">
<part name="return" type="xsd:string"/>
</message> |
Code :
1 2 3 4 5 6 7 8 9 10 11 12 | <binding name="BabelFishBinding" type="tns:BabelFishPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="BabelFish">
<soap:operation soapAction="urn:xmethodsBabelFish#BabelFish"/>
<input>
<soap:body use="encoded" namespace="urn:xmethodsBabelFish" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace="urn:xmethodsBabelFish" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding> |
Nun fehlt nur noch das Wissen, mit welche Datei kommunizieren muss. Dies wird im Service-Tag festgelegt .
Code :
1 2 3 4 5 6 7 | <service name="BabelFishService">
<documentation>Translates text of up to 5k in length, between a variety of languages.</documentation>
<port name="BabelFishPort" binding="tns:BabelFishBinding">
<soap:address location="http://services.xmethods.net:80/perl/soaplite.cgi"/>
</port>
</service>
</definitions> |
So ich hoffe nun weiß jeder, wie er solch eine Datei lesen muss. Es komm vielleicht noch ein wenig kompliziert vor, aber wenn man sich mehrere Dateien angeschaut hat kommt man schnell hinter das Prinzip.
8. Die eigene WSDL-Datei
Nun wollen wir für unseren eigenen Server auch so eine Datei erstellen, damit wir uns das arbeiten erleichtern können und somit auch den Server nach aussen hin benutzerfreundlicher machen.
testserver.wsdl:
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='TestServer'
xmlns:tns=' [url]http://example.com/testserver.wsdl[/url] '
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='addiereAnfrage'>
<part name='sum1' type='xsd:float'/>
<part name='sum2' type='xsd:float'/>
</message>
<message name='addiereAntwort'>
<part name='Result' type='xsd:float'/>
</message>
<portType name='TestServerPortType'>
<operation name='addiere'>
<input message='tns:addiereAnfrage'/>
<output message='tns:addiereAntwort'/>
</operation>
</portType>
<binding name='TestServerBinding' type='tns:TestServerPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='addiere'>
<soap:operation soapAction='urn:xmethodsTestServer#addiere'/>
<input>
<soap:body use='encoded' namespace='urn:xmethodsTestServer'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethodsTestServer'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='TestServerService'>
<port name='TestServerPort' binding='TestServerBinding'>
<soap:address location='http://{url}/server.php'/>
</port>
</service>
</definitions> |
Wer die Erklärung oben verstanden hat wird auch recht schnell die Veränderungen sehen und verstehen. Nun müssen wir nur noch unseren clienten auf diese Datei anpassen
client.php:
PHP-Code:
<?php
$client = new SoapClient('http://{url}/testserver.wsdl'); //{url} wie immer ersetzen
$result = $client->addiere(10, 20);
echo $result;
?>
Zu guter Letzt schreibe ich noch was zur Fehlerhandhabung.
Nehmen wir mal ein Beispiel. Du stellst ein Skript als SOAP-Server zu Verfüguung, welches in einer Datenbank nach Artikeln sucht. Nun gibt der Client aber keine Artikelbeschreibung an, wonach es dir nicht möglich ist, diese Abfrage durchzuführen. Dafür stellt SOAP extra ein Errorhandler bereit, wo man Errorcodes zurück an den Clienten schicken kann.
Bauen wir es am Besten gleich mal in unseren TestServer ein:
PHP-Code:
<?php
function addiere($sum1, $sum2) {
if(isset($sum1) && isset($sum2))
return $sum1 + $sum2;
else
return new SoapFault('Client', 'Eingabe nicht korrekt', 'server.php', '');
}
?>
Der erste Parameter ist der Fehler Code. Allgemein wird entweder 'Client' oder 'Server' benutzt. Client bedeutet dann soviel, dass der Fehler beim Clienten lag und Server demzufolge beim Server. Ihr könnt aber auch andere FehlerCodes nehmen.
Der zweite Parameter beinhaltet die Beschreibung des Fehlers.
Der dritte Parameter beinhaltet den Auslöser, also die Datei. Dieser Parameter ist optional.
Den vierten Paramter kann man auch nutzen, um weitere Informationen an den Clienten zu schicken. Er besitzt den Typ Mixed, also kann er alle möglichen Typen annehmen. Dieser Parameter ist ebenso optional.
Nun muss der Client aber darauf auch reagieren können. Dafür besitzt SOAP die Fkt. is_soap_fault(). Dabei ist zu beachten, dass die Option "exceptions" mit dem Wert 0 bei der Objekterstellung übergeben wird, weil sonst ein richtiger Fehler von SOAP erzeugt wird und man somit keine benutzerdefinierte Ausgabe vom Fehler machen kann.
client.php:
PHP-Code:
<?php
$client = new SoapClient('http://{url}/testserver.wsdl', array('exceptions' => 0)); //{url} wie immer ersetzen; Option 'exceptions' wir mit Wert 0 übergeben
$result = $client->addiere(10, 20);
if(is_soap_fault($result)) {
echo "FehlerCode: ", $result->faultcode, "\n";
echo "Beschreibung: ", $result->faultstring, "\n";
echo "Sender: ", $result->faultactor, "\n";
} else {
echo $result;
}
?>
So das war mein Tutorial und ich hoffe ich konnte euch SOAP in den Grundzügen erklären. Weitere Infos gibts natürlich auf www.php.net und weitere WSDL-Dateien findet ihr unter www.xmethods.net


Bereiche
Kategorien
Forum - Programming
tutorials.de-Systemmitteilung