PHP: SOAP – Web Service Client schreiben

Web Service ClientAm 10. Oktober 2011 habe ich behauptet, dass wirklich JEDER Java-Entwickler einen Web Service innerhalb von 15 Sekunden schreiben kann. Diese Behauptung konnte bisher keiner wiederlegen:-)
Darum behaupte ich heute, dass wirklich JEDER PHP-Entwickler einen Web Service Client in nur 10 Sekunden schreiben kann. Man brauch lediglich einen Web Service (WSDL + Endpoint) und einen php-fähigen Server (z.B. Apache). Lasst uns los legen und keine Zeit verlieren!

 

 

 

 

Das Environment

Die Grundvoraussetzung, um einen Web Service rufen zu können, ist die Erreichbarkeit des Entpoints/der WSDL. Diese können Sie ganz einfach testen, indem Sie die WSDL-URL im Browser eingeben. Bei meinem Beispiel sieht das Ergebnis so aus:
WSDL im Chrome
Zuvor habe ich das Beispiel “RechteckWS-Server” heruntergeladen, das Projekt in Eclipse importiert und die Server-Klasse ausgeführt…

 

Das PHP-Script

Die Zauberklasse in PHP heißt soapclient. MERKE: Der Name der Methode und der Attribute sind in der WSDL fest definiert!

<?php			

	// WSDL-URL_Adresse 
	// Kann lokal liegen oder per Endpoint (wie in diesem Beispiel) bezogen werden
	$client = new SoapClient("http://localhost:9202/rechteck/RechteckWebService?wsdl");
	
	// Änderung des Web Service Endpoints 
	$client->__setLocation('http://localhost:9202/rechteck/RechteckWebService');

	// Web Service Call
	//								Methoden Name		 	1. Parameter	2. Parameter
	$result = $client->__soapCall("berechneUmfang", array('Laenge' => 10, 'Breite' => 20));
	// oder
	$result = $client->berechneUmfang(array('Laenge' => 10, 'Breite' => 20));	
	
	// Zugriff auf das Ergebnis
	print $result->Umfang;
						

?>

…FERTIG!

HTML5 + PHP-Script

Das Ergebnis kann man auch in eine kleine Demo-Webseite verpacken. Auchtung die Webseite lag lokal auf einer XAMPP Installation! Die WSDL muss von dem entsprechenden Server erreichbar sein.

<!DOCTYPE html>
 
<html>
 
<head>
	<title>HTML5 RechteckWS Seite</title>
</head>
 
<body>
 
	<header>
		<h1>hallo Rechteck WS</h1>
	</header>
 

 
	<section>
 
		<article>
		
		
		<h1>WS Call</h1>
		
			<p>
				<?php			

					// WSDL-URL_Adresse 
					// Kann lokal liegen oder per Endpoint (wie in diesem Beispiel) bezogen werden
					$client = new SoapClient("http://localhost:9202/rechteck/RechteckWebService?wsdl");
					
					// Änderung des Web Service Endpoints 
					$client->__setLocation('http://localhost:9202/rechteck/RechteckWebService');

					// Web Service Call
					//								Methoden Name		 	1. Parameter	2. Parameter
					$result = $client->__soapCall("berechneUmfang", array('Laenge' => 10, 'Breite' => 20));
					// oder
					$result = $client->berechneUmfang(array('Laenge' => 10, 'Breite' => 20));	
					
					// druckt das Ergebnis
					var_dump ($result);
					
					print '<br />';
					
					// Zugriff auf das Ergebnis
					print $result->Umfang;
					
					print '<br />';							
				
				?>
			
			
			
			</p>
			
			
		</article>
 
	</section>
 

 
	<footer>
		<h1>AxxG</h1>
	</footer>
 
</body>
</html>

Demo-Webseite für einen Web Serice Call

 

Der Konstruktor der soapclient-Klasse

Im Normalfall reicht es, die WSDL-URL-Adresse im Konstruktor der soapclient-Klasse anzugeben. Jedoch lehrt uns die Wirklichkeit, dass es sehr viele Spezialfälle gibt:

<?php
// Standard
$client = new SoapClient("ein.wsdl");

// Standard + SOAP Version
$client = new SoapClient("ein.wsdl", array('soap_version'   => SOAP_1_2));

// Standard + HTTP Authentifizierung
$client = new SoapClient("ein.wsdl", array('login'          => "ein_name",
                                           'password'       => "ein_passwort"));

// Standard + Proxy
$client = new SoapClient("ein.wsdl", array('proxy_host'     => "localhost",
                                           'proxy_port'     => 8080));

// Standard + Proxy mit Verschluesselung
$client = new SoapClient("ein.wsdl", array('proxy_host'     => "localhost",
                                           'proxy_port'     => 8080,
                                           'proxy_login'    => "ein_name",
                                           'proxy_password' => "ein_passwort"));

// Standard + WSDL und Endpoint-Trennung
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));

// Standard + WSDL und Endpoint-Trennung + SOAP Spec
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/",
                                     'style'    => SOAP_DOCUMENT,
                                     'use'      => SOAP_LITERAL));

// Standard + Encoding
$server = new SoapClient("ein.wsdl", array('encoding'=>'ISO-8859-1'));
?>

 

Quellen und Links

 

Copyright © 2012 AxxG – Alexander Gräsel



11 Antworten : “PHP: SOAP – Web Service Client schreiben”

  1. Ein weiteres tolles Thema ist Web Service Security (WSS) oder WS-Security.

    Einen sehr schönen Artikel darüber findet ihr hier! (Stackoverflow)

  2. thomegg sagt:

    Normalerweise habe ich ja keinen Zugriff auf die Serverklassen. Meine einzige Informationsquelle ist das WSDL. Den Funktionsaufruf “berechneUmfang” kann ich aus dem WSDL entnehmen. Aber woher weiß ich dann eigentlich, dass die erforderlichen Variablen Laenge und Breite heißen?

    • Hallo,
      die Signatur der Methode befindet sich auch in der WSDL. Jedoch gibt es diverse Möglichkeiten die WSDL zu zerlegen. Zum Beispiel: In eine Schema.xml
      Der Verweis auf ggf. externen Dateien befindet sich immer in der WSDL. (Siehe Zeile 6)

      &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
      &lt;!-- Generated by JAX-WS RI at . RI's version is JAX-WS RI 2.1.6 in JDK 6. --&gt;
      &lt;definitions targetNamespace=&quot;http://www.axxg.de/ws/rechteck&quot; name=&quot;RechteckWebService&quot; xmlns=&quot;http://schemas.xmlsoap.org/wsdl/&quot; xmlns:tns=&quot;http://www.axxg.de/ws/rechteck&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;&gt;
        &lt;types&gt;
          &lt;xsd:schema&gt;
            &lt;xsd:import namespace=&quot;http://www.axxg.de/ws/rechteck&quot; schemaLocation=&quot;RechteckWebService_schema1.xsd&quot;/&gt;
          &lt;/xsd:schema&gt;
        &lt;/types&gt;
        &lt;message name=&quot;berechneUmfang&quot;&gt;
          &lt;part name=&quot;parameters&quot; element=&quot;tns:berechneUmfang&quot;/&gt;
        &lt;/message&gt;
        &lt;message name=&quot;berechneUmfangResponse&quot;&gt;
          &lt;part name=&quot;parameters&quot; element=&quot;tns:berechneUmfangResponse&quot;/&gt;
        &lt;/message&gt;
        &lt;message name=&quot;berechneInhalt&quot;&gt;
          &lt;part name=&quot;parameters&quot; element=&quot;tns:berechneInhalt&quot;/&gt;
        &lt;/message&gt;
        &lt;message name=&quot;berechneInhaltResponse&quot;&gt;
          &lt;part name=&quot;parameters&quot; element=&quot;tns:berechneInhaltResponse&quot;/&gt;
        &lt;/message&gt;
        &lt;portType name=&quot;RechteckWebService&quot;&gt;
          &lt;operation name=&quot;berechneUmfang&quot;&gt;
            &lt;input message=&quot;tns:berechneUmfang&quot;/&gt;
            &lt;output message=&quot;tns:berechneUmfangResponse&quot;/&gt;
          &lt;/operation&gt;
          &lt;operation name=&quot;berechneInhalt&quot;&gt;
            &lt;input message=&quot;tns:berechneInhalt&quot;/&gt;
            &lt;output message=&quot;tns:berechneInhaltResponse&quot;/&gt;
          &lt;/operation&gt;
        &lt;/portType&gt;
        &lt;binding name=&quot;RechteckWebServicePortBinding&quot; type=&quot;tns:RechteckWebService&quot;&gt;
          &lt;soap:binding transport=&quot;http://schemas.xmlsoap.org/soap/http&quot; style=&quot;document&quot;/&gt;
          &lt;operation name=&quot;berechneUmfang&quot;&gt;
            &lt;soap:operation soapAction=&quot;&quot;/&gt;
            &lt;input&gt;
              &lt;soap:body use=&quot;literal&quot;/&gt;
            &lt;/input&gt;
            &lt;output&gt;
              &lt;soap:body use=&quot;literal&quot;/&gt;
            &lt;/output&gt;
          &lt;/operation&gt;
          &lt;operation name=&quot;berechneInhalt&quot;&gt;
            &lt;soap:operation soapAction=&quot;&quot;/&gt;
            &lt;input&gt;
              &lt;soap:body use=&quot;literal&quot;/&gt;
            &lt;/input&gt;
            &lt;output&gt;
              &lt;soap:body use=&quot;literal&quot;/&gt;
            &lt;/output&gt;
          &lt;/operation&gt;
        &lt;/binding&gt;
        &lt;service name=&quot;RechteckWebService&quot;&gt;
          &lt;port name=&quot;RechteckWebServicePort&quot; binding=&quot;tns:RechteckWebServicePortBinding&quot;&gt;
            &lt;soap:address location=&quot;REPLACE_WITH_ACTUAL_URL&quot;/&gt;
          &lt;/port&gt;
        &lt;/service&gt;
      &lt;/definitions&gt;
      

      Die Schema.xml

      &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
      &lt;xs:schema version=&quot;1.0&quot; targetNamespace=&quot;http://www.axxg.de/ws/rechteck&quot; xmlns:tns=&quot;http://www.axxg.de/ws/rechteck&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
      
        &lt;xs:element name=&quot;berechneInhalt&quot; type=&quot;tns:berechneInhalt&quot;/&gt;
      
        &lt;xs:element name=&quot;berechneInhaltResponse&quot; type=&quot;tns:berechneInhaltResponse&quot;/&gt;
      
        &lt;xs:element name=&quot;berechneUmfang&quot; type=&quot;tns:berechneUmfang&quot;/&gt;
      
        &lt;xs:element name=&quot;berechneUmfangResponse&quot; type=&quot;tns:berechneUmfangResponse&quot;/&gt;
      
        &lt;xs:complexType name=&quot;berechneInhalt&quot;&gt;
          &lt;xs:sequence&gt;
            &lt;xs:element name=&quot;Laenge&quot; type=&quot;xs:float&quot;/&gt;
            &lt;xs:element name=&quot;Breite&quot; type=&quot;xs:float&quot;/&gt;
          &lt;/xs:sequence&gt;
        &lt;/xs:complexType&gt;
      
        &lt;xs:complexType name=&quot;berechneInhaltResponse&quot;&gt;
          &lt;xs:sequence&gt;
            &lt;xs:element name=&quot;Flaecheninhalt&quot; type=&quot;xs:float&quot;/&gt;
          &lt;/xs:sequence&gt;
        &lt;/xs:complexType&gt;
      
        &lt;xs:complexType name=&quot;berechneUmfang&quot;&gt;
          &lt;xs:sequence&gt;
            &lt;xs:element name=&quot;Laenge&quot; type=&quot;xs:float&quot;/&gt;
            &lt;xs:element name=&quot;Breite&quot; type=&quot;xs:float&quot;/&gt;
          &lt;/xs:sequence&gt;
        &lt;/xs:complexType&gt;
      
        &lt;xs:complexType name=&quot;berechneUmfangResponse&quot;&gt;
          &lt;xs:sequence&gt;
            &lt;xs:element name=&quot;Umfang&quot; type=&quot;xs:float&quot;/&gt;
          &lt;/xs:sequence&gt;
        &lt;/xs:complexType&gt;
      &lt;/xs:schema&gt;
      
  3. Carsten sagt:

    Da ich gerade dieAnbindung einer Mobile App an ein Webservice plane, kommt mir der Artikel wie gerufen. Danke dafür!

  4. Jürgen sagt:

    Hallo,

    ich möchte Dir natürlich nicht zu nahe treten aber sowohl Deine erste als auch Deine zweite Behauptung sind vollkommener nonsens. Wenn mir jemand einen Webservice anbietet, den er in wenigen Minuten zusammengeschustert hat, dann möchte ich den wirklich nicht sehen. In dieser Zeit kann sicherlich irgendwas ohne Sinn und Verstand kopiert werden und genau deshalb weiß ich auch gar nicht, wozu dieser Artikel überhaupt gut sein soll außer zur Google-Content-Mehrung.

    Eine WSDL schreibt man wirklich nicht selbst sondern läßt sie generieren. Was um Himmels Willen soll Deine WSDL für einen Nutzen haben?

    Entweder habe ich den Ergeiz einen guten Artikel zu schreiben (das geht auch nicht in ein paar Minuten) und mache mir dann wenigstens die Mühe zu erklären, was ich da überhaupt veranstalte. Du (sorry) rotzt einfach irgendeinen Kram in die Welt und überläßt dann großzügig dem Leser die Suche nach der eigentlichen Funktionsweise.

    Mir geht es echt langsam auf den Keks, dass immer mehr Leute meinen, sie müssen auf Gedeih und Verderb die Zeit anderer Leute verplempern.

    • Erst mal danke ich dir für dein Feedback. Jede Kritik, egal ob positiv oder negativ, bringt mich weiter.

      @Zielgruppe
      Mein Beitrag richtet sich in erster Linie an Entwickler, die ein entsprechendes Basiswissen (PHP, Web Service, XML) mitbringen. Ich fange selten bei Null an und fokussiere mich eher auf einfache/verständliche Beispiele.

      @Qualität
      Wie du schon gemerkt hast, kann man es nicht Allen recht machen. Dem Einen ist es zu viel Text, Theorie, Bilder und co – dem Anderen ist es zu wenig. Jedoch nötige ich niemanden meinen Blog zu lesen! Andere Seiten (zu finden unter der Überschrift “Quellen und Links”) beschreiben den gleichen Sachverhalt. Z.B.:http://www.html-world.de/program/phpex_9.php
      Des Weiten gibt es noch Suchmaschinen, Foren und co.

      @Empfehlung
      Ich empfehle dir die Seiten http://www.blogger.com oder http://de.wordpress.com/. Auf diesen Seiten kann man sich kostenlos einen Blog anlegen.

    • PL07 sagt:

      Kann euch beiden zustimmen in einigen Punkten zustimmen.

      @Jürgen
      Sicherlich ist es für eine gewissen Benutzergruppe schwierig solch ein umfassendes Thema ohne genügend Basis-Wissen zuverstehen. Ich als Gelegenheits-Blogger mag es auch lieber komplett erklärt, so dass keine Rückfragen notwendig sind. In diesem Punkt gebe ich dir recht.

      Es gibt aber eben auch Menschen, die suchen für ihre Problemlösung ein gut aufbearbeiteten Beitrag zu einem bestimmen Thema, welches Anhaltspunkte für genau ihr Problem bietet, ohne dabei zu weit auszuholen. Von daher sollte man als Leser sich bewusst sein, dass es für einen Blogger nicht möglich ist – auch wenn es eine einfache Überschrift so suggeriert – genau den Content zu liefern den man sich vorstellt.

      Und dafür gibt es eben nicht nur einen Blog der über Thema XY schreibt sondern x belibige mit unterschiedlichen Stilen und Motivationen. Aus diesem Grund gebe ich Alex recht in seinem Kommentar recht und finde es aber dennoch gut, dass du diesen Kommetar postest, da es ja auch dein gutes Recht ist deine Meinung hier zu äußern. Jedoch würde ihr dir nahelegen, beim nächsten Mal die hier diskutierten Sachverhalte zu berücksichtigen.

      Was man diesem Blog hier zu gute halten muss, ist das der Alex im dem Grundgedanken des Internets nachkommt und fleißig auch seine Quellen und weiterführende Links mitangibt, so dass ein interessierter Leser einen aufgezeigten Weg bekomtm, wo er nach weiteren (ihm fehlende) Informationen suchen kann.

      Zum Abschluss: noch ein Zitat aus einem bekannten Blog:

      “Womit wir beim bloggen wären. Ich finde, es sollten noch viel mehr machen. Also bloggen. Man liest ja immer, dass Blogs tot sind. So ein Bullshit. Blogs werden immer mehr. Jeder ist ein eigener Sender. Der eine macht Food, der andere Autos, der andere Schminke oder Mode. Ich mache halt Technik-Gedöns. Aber wichtig ist: macht es! Ich will euch lesen! Unabhängige Stimmen, die mir von ihren Erfahrungen in 1000 Kategorien des Lebens erzählen!” [Caschy, 4. März 2013, http://stadt-bremerhaven.de/ich-blogge-jetzt-8-jahre-und-wollte-euch-was-sagen/

Trackbacks/Pingbacks

  1. KW7: Amazon-Bericht, Push-Notifications, PHP-Webservice-Client und mehr | Der Softwareentwickler Blog - [...] Hier geht es zu diesem PHP-Tutorial. [...]

Kommentar verfassen