Kategorien
Webdesign

Workshop Webservices: Eigene Webservices entwickeln

Der eigene Webservice auf Basis von SOAP muss kein Traum bleiben. So gelingt der Einstieg… Die Entwicklung eigener Webservices mit PHP ist dank der NuSoap Klasse gar kein Problem. Zunächst wollen wir einen einfachen Webservice konstruieren. Er wird vom Client…

Der eigene Webservice auf Basis von SOAP muss kein Traum bleiben. So gelingt der Einstieg…

Die Entwicklung eigener Webservices mit PHP ist dank der NuSoap Klasse gar kein Problem. Zunächst wollen wir einen einfachen Webservice konstruieren. Er wird vom Client aufgerufen und gibt lediglich einen Text zurück, der daraufhin ausgegeben wird.

Dazu benötigen wir an erster Stelle einen Server, der die Anfragen sinngemäß beantwortet. Ein solcher Server könnte wie folgt aussehen:

server.php

 <?php
    //NuSoap Bibliothek wird eingebunden
    require_once('NuSoap.php'); 
      //ein neuer Server wird erstellt
    $server = new soap_server; 
      //Die Funktion wird für den Server registriert
    $server->register('ausgabe'); 
      //die Funktion selbst
    function ausgabe ()
    {
    return "Text";
    }
    //Alle Anfragen werden an die Service-Methode weitergeleitet
    $server->service($GLOBALS['HTTP_RAW_POST_DATA']);
    exit();
    ?>

Der Aufbau des Servers ist schnell erklärt. Zunächst wird die NuSoap Bibliothek eingebunden. Daraufhin wird ein neuer Server erzeugt. Für diesen Server wird die Funktion „ausgabe“ registriert.

Ein solcher Prozess ist notwendig, da man sonst nicht zwischen den Funktionen unterscheiden könnte, die zum einem dem Client zugänglich sein sollen oder zum anderen nur für die Funktionalität des Webservices benötigt werden. Somit wird ein gewisses Maß an Sicherheit gewährleistet. Die letzte Zeile des Skriptes ist deshalb auch die wichtigste.

      $server->service($GLOBALS['HTTP_RAW_POST_DATA']);

Durch sie wird definiert, dass alle ankommenden SOAP Anfragen an die Service-Methode von NuSoap übergeben werden; diese verarbeitet die SOAP Anfrage und ruft die entsprechenden Funktionen auf (in unserem Beispiel die Funktion „ausgabe()“). Mit dieser Anweisung wird der Server initialisiert.

Zu dem Webservice gehört nun auch ein Client, der den Webservice aufruft. Dieser ist im folgenden Skript modelliert:

client.php

      <?php
    require_once('NuSoap.php');
    //erzeugen eines neuen Clients
    $client = new soapclient("http://www.ihredomain.de/webservice/server.php");

    echo $client->call('ausgabe');
    ?>

Der Code des Clients ist auch schnell erklärt. Zunächst muss die NuSoap Klasse eingebunden werden. Über new soapclient(„http://www.ihredomain.de/webservice/server.php“); wird ein neuer Client erzeugt.

Komplexere Webservices
Nun, da die ersten Schritte gemacht sind, können wir etwas mehr riskieren. Im nächsten Versuch geht es um ein kleines Contentsharing-Programm, mit dessen Hilfe Sie auf ihrer Website anderen Webmastern Ihren Content anbieten können.

Im Beispiel sind Sie der Anbieter von News-Inhalten. Diese sind in einer MySQL Datenbank hinterlegt. Über den Webservice möchten Sie es den Webmastern ermöglichen ihren Content einzubinden. Hierzu müssen diese Clients erstellen können, über welche diese zum Beispiel die aktuellen Schlagzeilen laden können.

Die Datenbanktabelle könnte wie folgt aussehen:

Füllen Sie eine solche Tabelle einfach mit ein paar Testwerten, damit Sie den Webservice „ausprobieren“ können. Um eine reale Anwendung zu modellieren, sollten Sie den Webservice auf ihrem eigenen Webserver ihrer Domain anlegen; den Webservice können Sie dann über einen Client auf ihrem „daheim“ Computer ansprechen.

Der Webservice
Der Webservice benötigt nun eine Funktion um die Datenbankverbindung aufzubauen und wieder zu schließen. Des Weiteren müssen die SQL-Anfragen nach den Wünschen der Clients modelliert werden; so soll der Client Abfragen nach einer bestimmten News-ID, sowie nach einer bestimmten Anzahl der aktuellsten Nachrichten stellen können.

Anhand des Beispiels werden auch einige Probleme bei der Verwendung von NuSoap ersichtlich.

Der Webservice Server könnte wie folgt aussehen…

      <?php
    require_once('NuSoap.php');
    $server = new soap_server;
    $server->register('news'); 
      function news($id, $count) {
    $fnews = new Cnews;
    if ($id != 0) {
    return $fnews->get_news_by_id($id);
    }
    if ($count != 0) {
    return $fnews->get_news_by_count($count);
    }
    } //end func
      $server->service($GLOBALS['HTTP_RAW_POST_DATA']);
    exit(); 
      class Cnews {
      //Verbindung mit DB und Auswahl der DB
    function connect() {
    $host = "localhost";
    $user = "benutzer";
    $password = "passwort";
    $db = "datenbank";
      mysql_connect($host, $user, $password);
    mysql_select_db($db);
    } //end func
      
    //eine bestimmte Anzahl $count an News wird ermittelt
    function get_news_by_count($count) {
    $this->connect();
    $sql = "Select * From news order by id DESC LIMIT 0,".$count;
    $res = mysql_query($sql);
    $i=0;
       while ($erg = mysql_fetch_array($res, MYSQL_ASSOC)) {
    $data[$i]['id'] = $erg['id'];
    $data[$i]['date'] = $erg['date'];
    $data[$i]['title'] = $erg['title'];
    $data[$i]['teaser'] = $erg['teaser'];
    $data[$i]['content'] = $erg['content'];
    $i++;
    } //end while
      mysql_close();
    return $data;
    } //end func
      
    //eine bestimmte News wird nach ihrer $id ermittelt
    function get_news_by_id($id) {
      $this->connect();
      $sql = "Select * From news where id=".$id;
    $res = mysql_query($sql);
    $i=0;
    while ($erg = mysql_fetch_array($res, MYSQL_ASSOC)) {
    $data[$i]['id'] = $erg['id'];
    $data[$i]['date'] = $erg['date'];
    $data[$i]['title'] = $erg['title'];
    $data[$i]['teaser'] = $erg['teaser'];
    $data[$i]['content'] = $erg['content'];
    $i++;
    } //end while
    mysql_close();
    return $data;
      } //end func
    } //end Class
    ?>

Es fällt auf, dass im Server eine Klasse Cnews definiert wird. Dies liegt daran, dass NuSoap in unserem Fall nicht mit den zwei Dimensionalen Arrays klar kommt; hierzu müsste man sich stärker in die Funktionsweise von NuSoap und auch die WSDL einarbeiten. In unserem Beispiel werden einfache Datentypen anhand der Informationen aus der Datenbank erstellt – mit diesen kann NuSoap umgehen.

Der Server selbst besteht nur aus einer Funktion „news“, an die zwei Parameter übergeben werden. Diese stellen unsere Auswahlmethoden dar – sollen also zum einen die jeweils aktuellsten News (die Anzahl wird durch den Paramter „count“ bestimmt) zurückgegeben werden, bzw. nur eine bestimmte News-Nachricht (bestimmt durch den Parameter ID).
Daraufhin wird ein Objekt der Klasse Cnews erstellt, über welches man auf die Methoden get_news_by_id($id) bzw. get_news_by_count($count)zugreifen kann. Über diese werden die zwei verschiedenen Abfragen gemacht, und die Ergebnisse in ein zweidimensionales Array überführt. Dieses Array hat die Form:

      $data[i][element]

Wobei i die Nummer des Datensatzes ist; wird ein Datensatz per ID ausgelesen, so ist i=0, werden drei Datensätze ausgelesen, so kann i entweder 0, 1 oder 2 sein. Über element wird auf die einzelnen Datenbankfelder zugegriffen.

Um nun die Funktionsweise zu verstehen, betrachten wir einen Client, der den Webservice konsumieren möchte.

      <html>
    <body>
    <?php
    require_once('NuSoap.php');
    $client=new soapclient('http://www.ihredomain.de/webservice/server.php');
    
      $param = array ('id' => '1',
    'count' => '0');
    $response = $client->call('news', $param);
    var_dump($response);
    echo '<h1>'.$response[0]['title'].'</h1>';
    echo '<p><b>'.$response[0]['teaser'].'</b></p>';
    echo '<p>'.$response[0]['content'].'</p>';
    ?>
    </body>
    </html>

Bei diesem Client wird die Neuigkeit aus der Datenbank mit der id=1 ermittelt. Auffallend ist, dass bei den Parametern die an die Funktion news des Webservices übergeben wird auch der Parameter „count“ definiert ist. Dieser hat den Wert 0. Das liegt an ebenfalls an gewissen Einschränkungen die NuSoap mit sich bringt. Würde man beispielsweise folgenden Client definieren:

      <html>
    <body>
    <?php
    require_once('NuSoap.php');
    $client=new soapclient('http://www.ihredomain.de/webservice/server.php');
    
      $param = array ('count' => '3');
    $response = $client->call('news', $param); 
      foreach ($response as $key=>$elem) {
    echo '<h1>'.$elem['title'].'</h1>';
    echo '<p><b>'.$elem['teaser'].'</b></p>';
    echo '<p>'.$elem['content'].'</p>';
    }
    ?>
    </body>
    </html>

So würde uns NuSoap die Nachricht mit der id=3 zurückgeben, anstatt den drei aktuellsten Einträgen in der Datenbank. Das liegt daran, dass NuSoap als Bibliothek bei der Verwendung von einfachen Arrays nicht zwischen den Indizes unterscheidet. Der erste übergebene Parameter ist für NuSoap immer eine ID. Das obige Beispiel funktioniert also nur wenn man

      $param = array ('id' => '0',
    'count' => '3');

an die Funktion „news“ übergibt. Deshalb wird im Server bei der Funktion news auch die folgende Fallunterscheidung gemacht:

      if ($id != 0) {
    return $fnews->get_news_by_id($id);
    }
    if ($count != 0) {
    return $fnews->get_news_by_count($count);
    }

Damit wird sichergestellt, dass die jeweils richtige Methode aufgerufen wird.

Wenn Sie sich die SOAP Nachrichten anschauen möchten, so können Sie dies ebenfalls im Client machen. Um besseres Debugging betreiben zu können sind können sie sich die SOAP Messages über echo $client->request; bzw. echo $client->response; ausgeben lassen.

In diesem letzten Teil des Webservices Workshop wurde nur ein kleiner Teil der Möglichkeiten, die dem Webworker durch das Programmieren eigener Webservices ermöglicht werden, vorgestellt. Auch konnte nur ein kleiner Teil der komplexen Welt des Zusammenspiels von PHP und SOAP über NuSoap vorgestellt werden.

Für interessierte möchte ich das Buch Webservices mit PHP aus dem Galileo Computing Verlag von Christian Wenz und Tobias Hauser vorschlagen; es bietet einen praktischen Einstieg in die Erstellung und Nutzung eigener Webservices. Des Weiteren empfiehlt sich die Webseite Xmethods, dort finden Sie zahlreiche andere Webservices, die Sie für ihre Website über PHP und NuSoap nutzbar machen können.

Von Thiemo Fetzer

Thiemo Fetzer lebt seit 2008 in London und promoviert dort im Fachbereich "Entwicklungsökonomie" an der London School of Economics. Zuvor hat er Wirtschaftswissenschaften, Mathematik und Informatik in Magdeburg und Ulm studiert.

9 Antworten auf „Workshop Webservices: Eigene Webservices entwickeln“

Zwar gut beschrieben, aber bei mir funktioniert das Tutorial leider nicht. Bekomme folgende Fehlermeldung:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‚http://xxx/ws/server.php‘ in /xxx/ws/client.php:4 Stack trace: #0 /xxx/ws/client.php(4): SoapClient->SoapClient(‚http://xxx….‘) #1 {main} thrown in /xxx/ws/client.php on line 4

Hej Roland,

hatte dasselbe Problem. Hab dann gegen die Beispiele von Scott Nichol (http://www.scottnichol.com/nusoapintro.htm) geprüft. Der schreibt zwar auf der genannten Seite auch immer $client=new soapclient(blablabla); aber funktioniert hat es nicht. Dann hab ich mir seine Samples angesehen, und siehe da:

$client = new nusoap_client(blablabla);

Und damit gings bei mir.

Shalom
NP

PS: Ganz simples Beispiel:

server.php
register(‚ausgabe‘);

// Funktionen implementieren
function ausgabe() {
return „Text“;
}

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : “;

$server->service($GLOBALS[‚HTTP_RAW_POST_DATA‘]);
exit();
?>

client.php
call(‚ausgabe‘);
?>

Schreibe einen Kommentar zu Stefan Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.