Jede Funktion oder öffentliche Methode einer Klasse kann in PHP 5 über
die Klasse SOAPServer als Webdienst verfügbar gemacht
werden.
Der Konstruktor der Klasse SOAPServer erwartet entweder
den Pfad zu einer WSDL-Beschreibung des Webdienstes als ersten Parameter
oder ein assoziatives Array, das Informationen wie die URL des Webdienstes
enthält, als zweiten Parameter. Wir betrachten zunächst den Fall, dass
keine WSDL-Beschreibung vorliegt. In
Beispiel 9.1
übergeben wir den Wert NULL als ersten Parameter sowie
ein Array mit der Konfiguration des Webdienstes als zweiten Parameter.
Mit der Methode setClass() des SOAPServer-Objektes
legen wir die Klasse fest, deren öffentliche Methoden wir über den
Webdienst verfügbar machen möchten. Mit der Methode handle()
"starten" wir den Webdienst. Das bedeutet, dass eine HTTP-Anfrage an das
Skript des SOAPServer-Objektes als Anfrage an den
Webdienst aufgefasst und entsprechend verarbeitet wird.
Beispiel 9.1: Der Hallo-Welt-Webdienst
<?php
class Webdienst {
public function halloWelt() {
return 'Hallo Welt';
}
}
try {
$server = new SOAPServer(
NULL,
array(
'uri' => 'http://localhost/HalloWelt'
)
);
$server->setClass('Webdienst');
$server->handle();
}
catch (SOAPFault $f) {
print $f->faultstring;
}
?>
Fehler, die während der SOAP-Verarbeitung auftreten, werden durch eine
SOAPFault-Ausnahme repräsentiert und können entsprechend
behandelt werden.
Nehmen wir einmal an, dass
Beispiel 9.1
unter der URL http://localhost.org/HalloWelt.php
erreichbar ist. Eine "normale" HTTP-Anfrage für dieses Dokument führt
zu einer SOAP-Fehlermeldung, wie sie
Abbildung 9.1
zeigt, da sie keine gültige Anfrage im SOAP-Format enthält.
Abbildung 9.1. Ausgabe: SOAP-Antwort auf eine HTTP-Anfrage
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Bad Request. Can't find HTTP_RAW_POST_DATA</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Über eine HTTP-Post-Anfrage
(Beispiel 9.2),
die im SOAP-XML-Format gestellt wird, können wir die Methode
halloWelt() der Klasse Webdienst
(Beispiel 9.1)
aufrufen.
Beispiel 9.2: Eine SOAP-Anfrage an den Hallo-Welt-Webdienst
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:si="http://soapinterop.org/xsd">
<SOAP-ENV:Body>
<ns1:halloWelt xmlns:ns1="http://localhost" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Hallo Welt
Eine solche Anfrage von Hand zu erstellen ist bereits in dem hier gezeigten
einfachen Beispiel (keine Parameter, einfacher String als Ergebnis) mühsam.
Im folgenden Abschnitt werden wir sehen, wie uns die Klasse SOAPClient
diese Arbeit abnimmt.
Doch zunächst beschreiben wir den Webdienst mit WSDL in der Datei
HalloWelt.wsdl
(Beispiel 9.3).
Die WSDL-Beschreibung enthält unter anderem Informationen über die Adresse
des Webdienstes sowie die Datentypen von Parametern und Rückgabewerten der
angebotenen Methoden.
Beispiel 9.3: Den Hallo-Welt-Webdienst mit einem WSDL-Dokument beschreiben
<?xml version ="1.0" encoding ="UTF-8" ?>
<definitions name="HalloWelt"
targetNamespace="http://localhost/HalloWelt"
xmlns:tns=" http://localhost/HalloWelt"
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="halloWeltResponse">
<part name="Result" type="xsd:string"/>
</message>
<portType name="HalloWeltPortType">
<operation name="halloWelt">
<output message="tns:halloWeltResponse"/>
</operation>
</portType>
<binding name="HalloWeltBinding" type="tns:HalloWeltPortType">
<soap:binding
style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="halloWelt">
<soap:operation soapAction="urn:hallowelt#halloWelt"/>
<output>
<soap:body
use="encoded"
namespace="urn:hallowelt"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="HalloWeltService">
<port name="HalloWeltPort" binding="HalloWeltBinding">
<soap:address location="http://localhost/HalloWelt.php"/>
</port>
</service>
</definitions>
Bei der Erzeugung des SOAPServer-Objektes können wir nun
anstelle von NULL und dem assoziativen Parameter-Array den
Pfad zur WSDL-Beschreibung aus
Beispiel 9.3
angeben (Beispiel 9.4).
Für eine HTTP-Anfrage an http://localhost/HalloWelt.php?wsdl
liefert das Skript nun die WSDL-Beschreibung aus.
Beispiel 9.4: Der Hallo-Welt-Webdienst mit WSDL-Beschreibung
<?php
class Webdienst {
public function halloWelt() {
return 'Hallo Welt';
}
}
try {
$server = new SOAPServer('HalloWelt.wsdl');
$server->setClass('Webdienst');
$server->handle();
}
catch (SOAPFault $f) {
print $f->faultstring;
}
?>