Kontakt aufnehmen

SOAP mit PHP

Bei der Entwicklung von Webanwendungen wird die Zukunft in die Richtung von service-orientierten Architekturen (SOA) gehen. In diesem Zusammenhang spielen die Webservices im allgemeinen eine große Rolle. Mit dem SOAP-Protokoll können auf eine einfache und kostenlose Art und Weise Informationen zwischen Webanwendungen übermittelt werden. SOAP wird hauptsächlich mit Java eingesetzt, aber eine entsprechende Erweiterung ist auch in anderen Programmiersprachen integriert.

Einführung in SOAP

Geschichte von SOAP

Für das SOAP-Protokoll gibt es keine bekannte Erklärung der einzelnen Buchstaben. Dies liegt daran, dass sämtliche kursierende Versuche wie Simple Object Access Protocol oder Service Oriented Architecture Protocol den kompletten Aufgabenbereich und Sinn des Protokolls nicht abdecken. 1999 wurde die erste Version von SOAP (0.9) veröffentlicht, die zunächst auf Skepsis stieß und erst nach der Veröffentlichung der Version 1.0 im gleichen Jahr stieg das Interesse bekannter Firmen wie Microsoft oder IBM an dem Protokoll. Nach der Einreichung beim W3C zur allgemeinen Standardisierung wurde im Jahr 2003 die bis jetzt aktuelle Protokollversion 1.2 veröffentlicht.

Funktionsweise von SOAP

Die Daten, die per SOAP übertragen werden, werden grundsätzlich in einer XML-Struktur dargestellt. Zur Übertragung sind verschiedene Protokolle der Internet-Protokollfamilie möglich, was in der jeweiligen SOAP-Anwendung eingerichtet werden muss. Das HTTP-Protokoll ist die am häufigsten genutzte Variante, wobei auch eine Übertragung über HTTPS möglich ist. Die Protokolle "SMTP" oder "FTP" sind im Zusammenhang mit SOAP zwei mögliche Alternativen.
Die SOAP-Kommunikation basiert auf einer Client-Server-Architektur, was bedeutet, dass der Client die Informationen an den Server, der über eine URI aufgerufen wird, übermittelt und von ihm eine Antwort erhält, die der Client dann weiter verarbeiten kann.

Einsatzgebiete von SOAP

Es ist nicht einfach, konkrete Einsatzgebiete zu definieren. Im wesentlichen spricht ein Punkt für die Nutzung von SOAP und das ist der, wenn die Anwendung zum Abruf der Informationen keinen direkten Zugang zur Datenquelle haben soll (z.B. Zugriff auf eine Datenbank) oder darf. Das kann zum einen sicherheitstechnische Gründe haben und zum anderen ist es u. U. zu aufwändig, eine Schnittstelle zwischen zwei Anwendungen zu programmieren, wenn deren Architektur zu unterschiedlich ist. Hier schafft SOAP einen vergleichsweise einfachen Weg, die Daten untereinander auszutauschen. Ein bekanntes Einsatzgebiet von SOAP sind die Suchanzeigen bekannter Anbieter wie Amazon oder Ebay, die auf Partnerseiten eingebunden sind.

Aufbau einer SOAP-Nachricht

Die allgemeine Struktur einer SOAP-Nachricht sieht so aus:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://www.w3.org/2001/12/soap-envelope">
    <s:Header>
    </s:Header>
    <s:Body>
    </s:Body>
</s:Envelope>

Sie besteht innerhalb einer XML-Struktur aus einem SOAP-Envelope (dt. Umschlag), in der sich ein Header- und ein Body-Element befindet. Der angegebene Namensraum ist bei jeder SOAP-Nachricht gleich. Im Header-Element befinden sich "organisatorische" Daten wie Details zum Routing oder zur Verschlüsselung. Während das Header-Element optional ist, muss das Body-Element zwingend angegeben werden, da es zur Übertragung der Daten dient.
Der Programmierer der SOAP-Anwendung muss sich aber keine Sorgen machen, dass er sich mit XML auch noch auseinandersetzen muss. Die SOAP-Nachrichten werden grundsätzlich automatisch angelegt und auch interpretiert, so dass der Einsatz z.B. eines XML-Parsers o. ä. nicht notwendig ist.

SOAP und WSDL!?

Im Zusammenhang mit SOAP taucht oft der Begriff "WSDL" auf. Dies ist die Abkürzung von Web Services Description Language und stellt ein XML-basiertes Schema / Prinzip zur Verfügung, um Webservices zu beschreiben. Bezogen auf SOAP heißt das nichts anderes, als das in der WSDL-Datei alle Informationen wie Namespace, Zeichensatz, Pfad zum Server usw. hinterlegt werden können und nicht mehr direkt im Client- oder Serverskript mit angegeben werden müssen. Für WSDL gilt der Grundsatz, dass damit gearbeitet werden kann, aber nicht muss.

SOAP und PHP

Freischaltung der Extension

Seit der Version 5 von PHP wird standardmäßig eine Extension für SOAP mitgeliefert, die in der php.ini-Datei aber noch freigeschaltet werden muss. Zu diesem Zweck sucht man sich die Zeile ";extension=php_soap.dll" in der Datei heraus. Danach entfernt man das Semikolon am Anfang, speichert die Datei und startet den Webserver neu. Die Extension steht jetzt zur Verfügung.

SOAP-Parameter in der php.ini

Die php.ini-Datei bietet verschiedene Parameter an, mit der eine SOAP-Umgebung konfiguriert werden kann. In der folgenden Tabelle werden alle Parameter sowie deren vorkonfigurierten Werte dargestellt.

Parameter Default-Wert Bedeutung
soap.wsdl_cache_enabled 1 aktiviert oder deaktiviert den WSDL-Cache
soap.wsdl_cache_dir /tmp Verzeichnis für den WSDL-Cache
soap.wsdl_cache_ttl 86400 Zeitraum in Sekunden wie lange zwischengespeicherte WSDL-Dateien genutzt werden sollen
soap.wsdl_cache_limit 5 maximale Anzahl von WSDL-Dateien, die gespeichert werden können
Die Nutzung von WSDL ist bei SOAP nicht zwingend notwendig. Das bedeutet, dass man die Parameter in der php.ini nur dann verändern sollte, wenn man auch mit WSDL arbeiten möchte.

Funktionen für den SOAP-Client

Die SOAP-Programmierung wird bei PHP objektorientiert realisiert. Das bedeutet, dass zuerst eine Instanz für ein SOAP-Client-Objekt angelegt werden muss. Dies geschieht durch den folgenden Code:

$soap = new SoapClient( 
 null, 
 array( 
       "location" => "http://localhost/soap/soapserver.php",
       "uri" => "http://test-uri",
       "soap_version" => SOAP_1_1,
       "trace" => 1
      ) 
 );

Bei den Parameternfür die Objekt-Instanz kommt es darauf an, ob mit WSDL gearbeitet werden soll oder nicht. Es ist üblich, in der Entwicklung auf WSDL zu verzichten, um sich nicht um ein weiteres Feature kümmern zu müssen. Wenn also kein WSDL-File benötigt wird, muss stattdessen das "null" als Parameter (siehe Beispiel) angegeben werden. Wenn das der Fall ist, ist es gleichzeitig notwendig, alle benötigten Parameter in einem assoziativen Array anzugeben. In der folgenden Tabelle werden die wichtigsten Parameter sowie deren Bedeutung und Priorität aufgelistet.

Parameter Bedeutung Priorität
location Ort des SOAP-Server-Skriptes notwendig
uri Namespace des SOAP-Service notwendig
soap_version Eingesetzte Protokollversion optional
login Loginname für HTTP-Authenifizierung optional
password Passwort für HTTP-Authenifizierung optional
compression Komprimierung des SOAP-Requests optional
encoding (*) Zeichensatz für SOAP-Request optional
trace Möglichkeit zur Analyse des SOAP-Requests optional
local_cert Zertifikatspfad für SSL-Kommunikation optional
proxy_host Ort des Proxy-Servers optional
proxy_port IP-Port des Proxy-Servers optional
proxy_login Login für den Proxy-Server optional
proxy_password Passwort für den Proxy-Server optional
(*) Dabei wird nicht der Zeichensatz des SOAP-Requests verändert. Dafür wird grundsätzlich UTF-8 verwendet. Dieser Parameter beeinflusst die Darstellung der übermittelten Nutzer-Informationen.

Nach dem Anlegen der Objektinstanz für den SOAP-Client müssen die Aufrufe für die Funktionen des SOAP-Servers festgelegt werden. Dazu gibt es zwei Möglichkeiten, die der Programmierer frei nach seinem Willen einsetzen kann.

Funktionsaufruf als Objekt-Methode

Die einfachere Variante ist ein Funktionsaufruf nach dem üblichen Prinzip, wie die Methode eines Objektes in PHP aufgerufen wird. Der folgende Code zeigt ein entsprechendes Beispiel:

$result= $soap->testfunktion("Michael");

Damit wird auf dem Server die Funktion "testfunktion", der der Parameter "Michael" übergeben wird, aufgerufen. Es steht dem Programmierer frei, ob er die Parameter als Array oder einzeln übergibt. In der Variable $result ist der Rückgabewert enthalten, wobei automatisch ermittelt wird, ob es sich um eine Variable oder um ein Array handelt.

Funktionsaufruf mit Client-Funktion

Eine Alternative für den Funktionsaufruf ist die Funktion __soapCall, die mit der SOAP-Extension mitgeliefert wird. Wenn diese Funktion verwendet wird, müssen die Parameter zwingend als Array übergeben werden. Der folgende Codeausschnitt zeigt ein Anwendungsbeispiel:

$result = $soap->__soapCall("testfunktion", array("Michael"));

Hier entspricht der Funktionsname einem übergebenen Parameter. Ansonsten gibt es keinen weiteren Unterschied zur ersten Alternative.

Fehlerbehandlung bei SOAP-Requests

Der Programmierer hat verschiedene Möglichkeiten, dass bei einem SOAP-Request ein Fehler auftreten kann. Die zwei gängigsten Beispiele sind ein Schreibfehler beim Funktionsnamen oder beim Pfad zum Serverskript, so dass der Request ins Leere geht. Die PHP-SOAP-Extension bietet mehrere Funktionen, um sich einen aufgetretenen Fehler anzeigen und analysieren lassen zu können.
Es empfiehlt sich auf jeden Fall die Funktion is_soap_fault() zu verwenden, denn damit kann überprüft werden, ob ein Fehlerfall vorliegt oder nicht. Im Zusammenhang mit einer trivialen if-Schleife ist diese Funktion am sinnvollsten eingesetzt.

if(is_soap_fault($result))
{
 print(" Fehlercode: $result->faultcode | Fehlerstring: 
         $result->faultstring");
}
else
{
 print "$result<br>";
}

Die Funktion bezieht sich immer auf einem bestimmten Funkionsaufruf, so dass als Parameter der Rückgabewert des entsprechenden Aufrufes mit übergeben werden muss. Wenn die Bedingung if(is_soap_fault($result)) erfüllt ist, wird die Fehlermeldung ausgegeben. Die Fehlermeldungen können in unterschiedlicher Art und Weise ermittelt werden, wofür standardmäßig die Methoden zur Verfügung gestellt werden. Mit der Eigenschaft faultcode wird ein SOAP-Fehlercode angezeigt, der alleine noch nicht aussagekräftig ist. Die Eigenschaft faultstring liefert eine ausführliche Beschreibung zum Fehlercode. Die Eigenschaft faultactor gibt einen Hinweis zurück, bei welcher Komponente, die der SOAP-Request durchlaufen hat, der Fehler aufgetreten ist.
Wen das noch nicht zufrieden stellt, kann mit der Funktion trigger_error() auch eigene Fehlermeldungen generieren. Dazu muss neben dem eigenen Fehlertext noch die PHP-Kategorie, die in diesem Fall "E_USER_ERROR" lautet, angegeben werden.

Funktionen für den SOAP-Server

Nachdem der SOAP-Client fertig ist, muss nun das Skript für den SOAP-Server programmiert werden. Auch hier muss zuerst die Instanz für ein Serverobjekt angelegt werden, was durch folgenden Code realisiert werden kann:

$server = new SoapServer( 
 null, 
 array( 
  'uri'=>"http://localhost/test-uri",
  'encoding'=>'UTF-8', 
  'soap_version'=>SOAP_1_2
 ) 
);

Auch beim Server gibt man als ersten Parameter entweder die WSDL-Datei oder das NULL an, wenn nicht mit WSDL gearbeitet werden soll. Alle weiteren Parameter müssen zwingend als assoziatives Array mit angegeben werden. In der folgenden Tabelle werden die gängigsten Parameter für das Serverobjekt beschrieben.

Parameter Bedeutung Priorität
uri Namespace des SOAP-Service notwendig wenn WSDL nicht genutzt wird
soap_version Eingesetzte Protokollversion optional
encoding Zeichensatz für SOAP-Request optional
Speziell bei der Angabe der URI sollte man aufpassen, dass die Information beim Serverobjekt mit der Angabe beim Clientobjekt übereinstimmt. Um dieses zu verdeutlichen, werden die beiden Angaben verglichen.

Client: "uri" => "http://test-uri"
Server: "uri" => "http://localhost/test-uri"

Hinweis: Eine weitere typische Fehlerquelle bei SOAP-Anwendungen ist die Nicht-Übereinstimmung der Definitionen für den Namespace.

Ausführen eines SOAP-Requestes

Der gedankliche Ausgangspunkt ist, dass zum jetzigen Zeitpunkt der SOAP-Request von Client mit allen notwendigen Informationen (Funktionsnamen, Parameter) angekommen ist. Jetzt muss dem Server mitgeteilt werden, dass er den Request auch ausführen soll. Das bedeutet, er muss die entsprechende Funktion aufrufen, die Informationen für die Response ermitteln und eine Antwort zum Client zurückschicken. Diese Aufgaben übernimmt pauschal die Funktion handle(), die im Server-Skript ohne weiteren Parameter angegeben werden muss.

$server->handle();

Hinzufügen von Server-Funktionen oder Server-Klassen

Die Informationen für den SOAP-Client können innerhalb des Servers über Funktionen oder Klassen ermittelt werden. Dafür gilt das allgemeine Prinzip, dass die Funktionen bzw. Klassen zum Server hinzugefügt werden müssen. Manchmal taucht auch die Formulierung auf, dass die Funktionen/Klassen beim Server registriert werden müssen. Um diese Aufgabe zu erfüllen, gibt es zwei Funktionen - addFunction() für die Funktion(en) und setClass() für die Klasse(n).

$server->addFunction("testfunktion");

In diesem Beispiel wird die Funktion testfunktion dem SOAP-Server hinzugefügt. Eine Angabe der Parameter für die Funktion ist nicht erforderlich. Mit addFunction können mehrere Funktionen gleichzeitig registriert werden. Wenn dies genutzt werden soll, müssen die einzelnen Funktionsnamen als Elemente eines Arrays mit angegeben werden.
Das Hinzufügen einer Klasse wird durch das folgende Codebeispiel realisiert:

$server->setClass("testklasse", $param1, $param2);

Obwohl es möglich ist, besteht keine Notwendigkeit, die Parameter mit anzugeben.

Hinweis: Mit der Funktion setPersistence() kann man anderen Skripten oder Sessions erlauben, auf die Klasse im SOAP-Server zuzugreifen.

Ermitteln der Informationen im SOAP-Server

Zur Ermittlung der Informationen im Server können Klassen oder Funktionen verwendet werden. Beides wird nach dem bekannten Prinzipien definiert und ganz einfach mit im Serverskript angegeben. Der folgende Code zeigt ein Beispiel für die Definition einer Funktion:

function testfunktion($param)
{
 return "Hallo" . $param . "!! Es funktioniert!!!";
}

Über die handle()-Funktion wird der Parameter an die Funktion übergeben und kann innerhalb der Funktion nach dem üblichen Prinzip verarbeitet werden. Um die Information für die Antwort des Servers bereitzustellen, muss diese mit dem Schlüsselwort return wieder zurückgegeben werden.

Du arbeitest in einer Agentur oder als Freelancer?
Dann wirf doch mal einen Blick auf unsere Software FeatValue.

Weiterlesen: ⯈ PEAR

Über uns

Stefan Wienströer

Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project

Cookie-Einstellungen

Helfen Sie dabei, uns noch besser zu machen. Wir nutzen Cookies und ähnliche Technologien, um die Website auf Ihre Bedürfnisse anzupassen. Zur Datenschutzerklärung

Auswahl speichern