• Ce blog — désormais archivé — est en lecture seule.

Découverte des WebServices en PHP

Et oui, en PHP on peut faire des webservices. Mais un WebService c’est quoi d’abord ?

C’est un programme sur Internet qui permet la communication et l’échange de données entre applications. Ce sont des fonctionnalités, des services mis à disposition sur Internet (ou Intranet) et accessibles par tout le monde.

C’est interopérable, c’est basé sur HTTP (donc pas de soucis au niveau des parefeux), on utilise des standards et des protocoles ouverts, et c’est l’avenir du web. Bref, puissant !

Principe de fonctionnement

Dans l’exemple illustré, le Client veut savoir le temps qu’il fait.

- En 1, Il va demandé à un annuaire de webservices (UDDI) où il peut trouver un tel service.

- En 2, l’annuaire lui indique où est le service qui pourra le renseigner.

- En 3, le client demande au service comment l’invoquer (c’est-à-dire comment bien lui demander un service).

- En 4, le service renvoit sa déscription (WSDL) où est indiqué comment invoquer ce service.

- En 5, le client invoque le service en envoyant une requête SOAP.

- En 6, le service renvoit la réponse au client dans une réponse (toujours en SOAP).

Un service web en PHP

En PHP, on peut faire des webservices, que ce soit en tant que client ou en tant que serveur comme je vais expliquer dans ce qui suit. Il faudra préalablement avoir le module php_soap installé et activé.

Mon webservice sera simple, il disposera de deux méthodes :

- La première se nommera hello() et retournera « Hello world! ».

- La deuxième s’appellera donne(), prendra une variable en attribut et la retournera.

class Donne
{
  function donne($i)
  {
    return $i;
  }
  function hello()
  {
    return "hello world";
  }
}

La classe ci-dessus représente les fonctionnalités de mon webservice. Il s’agit maintenant de le mettre en place, c’est que fait le code ci-après :

try
{
  $server = new SoapServer(null, array('uri' => 'http://monserveur/ws/mon_premier_webservice.php'));

  $server->setClass("Donne");
  $server->handle();
}
catch(Exception $e)
{
  echo "Exception: " . $e;
}

On commence par créer un objet SoapServer qui prend en arguments un fichier WSDL (null ici) et une liste de paramètres. Si le fichier WSDL n’est pas renseigné comme ici, il faut obligatoirement spécifier le paramètre URI ensuite.

Ensuite, on va indiquer à notre serveur, la classe qui gère les requêtes SOAP par la méthode setClass(). La méthode handle() fait le nécessaire pour gérer une requête SOAP.

Voilà c’est tout, pour être disponible, il faut placer notre service à l’adresse : http://monserveur/ws/mon_premier_webservice.php.

L’URI qui représente l’espace de nom, est différente de la Location du service qui est l’URL à interroger.

Un client pour mon premier webservice

L’utilité d’un webservice, c’est de pouvoir l’exploiter. On va donc développer un petit client en PHP pour invoquer notre service web précédemment écrit.

Voici le code de notre petit client :

<?php

try
{
  $clientSOAP = new SoapClient( null,
    array (
      'uri' => 'http://monserveur/ws/mon_premier_webservice.php',
      'location' => 'http://monserveur/ws/mon_premier_webservice.php',
      'trace' => 1,
      'exceptions' => 0
  ));

  $ret = $clientSOAP->__call('hello', array());
  echo $ret;

  echo '<br />';

  $ret = $clientSOAP->__call('donne', array('i'=>5));
  echo $ret;
}
catch(SoapFault $f)
{
  echo $f;
}

?>

Ce code teste les deux méthodes de notre service. On crée cette fois-ci un SoapClient.

On travaille toujours en mode non WSDL, il faut passer obligatoirement deux paramètres qui sont URI et Location. Trace et Exception sont utiles lorsqu’un problème survient.

Pour appeler une méthode, on utilise la méthode __call(). Pour passer les paramètres à une fonction, il suffit de passer un tableau associatif.

Et voilà, ce n’est finalement pas si compliqué !

Un client plus élaboré pour un service Whois

Pour étoffer cet article, voici un exemple d’utilisation des webservices. Sur le site http://www.xmethods.net/ qui présente des services web, j’ai choisi un service Whois. Le site donne le lien de la description WSDL du service web. C’est tout ce dont nous avons besoin.

Présentation du web service :

Whois service lets users get domain information from any registry.

Servername is the whois server to be used.Some commonly queried whois servers are:- whois.networksolutions.com- whois.35.com- whois.tucows.com

Port is always 43 for whois servers.Domain is the domain name that you want to query.

La description WSDL de notre service Whois est disponible ici : http://www.ecubicle.net/whois_service.asmx?WSDL, voici ce que l’on récupère :

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.ecubicle.net/webservices/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.ecubicle.net/webservices/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.ecubicle.net/webservices/">
<s:element name="HelloWorld">
<s:complexType />
</s:element>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>

<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Whois">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="servername" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="port" type="s:unsignedByte" />

<s:element minOccurs="0" maxOccurs="1" name="domain" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="WhoisResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="WhoisResult" type="s:string" />
</s:sequence>

</s:complexType>
</s:element>
<s:element name="string" nillable="true" type="s:string" />
</s:schema>
</wsdl:types>
<wsdl:message name="HelloWorldSoapIn">
<wsdl:part name="parameters" element="tns:HelloWorld" />
</wsdl:message>
<wsdl:message name="HelloWorldSoapOut">

<wsdl:part name="parameters" element="tns:HelloWorldResponse" />
</wsdl:message>
<wsdl:message name="WhoisSoapIn">
<wsdl:part name="parameters" element="tns:Whois" />
</wsdl:message>
<wsdl:message name="WhoisSoapOut">
<wsdl:part name="parameters" element="tns:WhoisResponse" />
</wsdl:message>
<wsdl:message name="HelloWorldHttpGetIn" />

<wsdl:message name="HelloWorldHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="WhoisHttpGetIn">
<wsdl:part name="servername" type="s:string" />
<wsdl:part name="port" type="s:string" />
<wsdl:part name="domain" type="s:string" />
</wsdl:message>
<wsdl:message name="WhoisHttpGetOut">

<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="HelloWorldHttpPostIn" />
<wsdl:message name="HelloWorldHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="WhoisHttpPostIn">
<wsdl:part name="servername" type="s:string" />
<wsdl:part name="port" type="s:string" />

<wsdl:part name="domain" type="s:string" />
</wsdl:message>
<wsdl:message name="WhoisHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:portType name="whois_serviceSoap">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldSoapIn" />
<wsdl:output message="tns:HelloWorldSoapOut" />

</wsdl:operation>
<wsdl:operation name="Whois">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Whois service lets users get domain information from any registry. &lt;br/&gt;&lt;h4&gt; Servername&lt;/h4&gt; is the whois server to be used.&lt;br/&gt;Some commonly queried whois servers are: &lt;br/&gt;&lt;ul&gt;&lt;li&gt;whois.networksolutions.com&lt;/li&gt;&lt;li&gt;whois.35.com&lt;/li&gt;&lt;li&gt;whois.tucows.com&lt;/li&gt;&lt;/ul&gt; &lt;br/&gt;&lt;br/&gt;&lt;h4&gt; Port &lt;/h4&gt;is always 43 for whois servers. &lt;br/&gt;&lt;br/&gt;&lt;h4&gt;Domain &lt;/h4&gt;&lt;br/&gt;is the domain name that you want to query.</wsdl:documentation>

<wsdl:input message="tns:WhoisSoapIn" />
<wsdl:output message="tns:WhoisSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="whois_serviceHttpGet">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldHttpGetIn" />
<wsdl:output message="tns:HelloWorldHttpGetOut" />
</wsdl:operation>

<wsdl:operation name="Whois">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Whois service lets users get domain information from any registry. &lt;br/&gt;&lt;h4&gt; Servername&lt;/h4&gt; is the whois server to be used.&lt;br/&gt;Some commonly queried whois servers are: &lt;br/&gt;&lt;ul&gt;&lt;li&gt;whois.networksolutions.com&lt;/li&gt;&lt;li&gt;whois.35.com&lt;/li&gt;&lt;li&gt;whois.tucows.com&lt;/li&gt;&lt;/ul&gt; &lt;br/&gt;&lt;br/&gt;&lt;h4&gt; Port &lt;/h4&gt;is always 43 for whois servers. &lt;br/&gt;&lt;br/&gt;&lt;h4&gt;Domain &lt;/h4&gt;&lt;br/&gt;is the domain name that you want to query.</wsdl:documentation>

<wsdl:input message="tns:WhoisHttpGetIn" />
<wsdl:output message="tns:WhoisHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="whois_serviceHttpPost">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldHttpPostIn" />
<wsdl:output message="tns:HelloWorldHttpPostOut" />
</wsdl:operation>

<wsdl:operation name="Whois">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Whois service lets users get domain information from any registry. &lt;br/&gt;&lt;h4&gt; Servername&lt;/h4&gt; is the whois server to be used.&lt;br/&gt;Some commonly queried whois servers are: &lt;br/&gt;&lt;ul&gt;&lt;li&gt;whois.networksolutions.com&lt;/li&gt;&lt;li&gt;whois.35.com&lt;/li&gt;&lt;li&gt;whois.tucows.com&lt;/li&gt;&lt;/ul&gt; &lt;br/&gt;&lt;br/&gt;&lt;h4&gt; Port &lt;/h4&gt;is always 43 for whois servers. &lt;br/&gt;&lt;br/&gt;&lt;h4&gt;Domain &lt;/h4&gt;&lt;br/&gt;is the domain name that you want to query.</wsdl:documentation>

<wsdl:input message="tns:WhoisHttpPostIn" />
<wsdl:output message="tns:WhoisHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="whois_serviceSoap" type="tns:whois_serviceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="HelloWorld">
<soap:operation soapAction="http://www.ecubicle.net/webservices/HelloWorld" style="document" />
<wsdl:input>

<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Whois">
<soap:operation soapAction="http://www.ecubicle.net/webservices/Whois" style="document" />
<wsdl:input>

<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="whois_serviceSoap12" type="tns:whois_serviceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:operation name="HelloWorld">
<soap12:operation soapAction="http://www.ecubicle.net/webservices/HelloWorld" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>

<wsdl:operation name="Whois">
<soap12:operation soapAction="http://www.ecubicle.net/webservices/Whois" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>

</wsdl:binding>
<wsdl:binding name="whois_serviceHttpGet" type="tns:whois_serviceHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="HelloWorld">
<http:operation location="/HelloWorld" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>

<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Whois">
<http:operation location="/Whois" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>

<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="whois_serviceHttpPost" type="tns:whois_serviceHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="HelloWorld">
<http:operation location="/HelloWorld" />
<wsdl:input>

<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Whois">
<http:operation location="/Whois" />
<wsdl:input>

<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="whois_service">
<wsdl:port name="whois_serviceSoap" binding="tns:whois_serviceSoap">

<soap:address location="http://www.ecubicle.net/whois_service.asmx" />
</wsdl:port>
<wsdl:port name="whois_serviceSoap12" binding="tns:whois_serviceSoap12">
<soap12:address location="http://www.ecubicle.net/whois_service.asmx" />
</wsdl:port>
<wsdl:port name="whois_serviceHttpGet" binding="tns:whois_serviceHttpGet">
<http:address location="http://www.ecubicle.net/whois_service.asmx" />
</wsdl:port>
<wsdl:port name="whois_serviceHttpPost" binding="tns:whois_serviceHttpPost">

<http:address location="http://www.ecubicle.net/whois_service.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

Seul le début nous intéresse. Par exemple, on voit que ce service propose deux fonctionnalités : HelloWorld et Whois.

- HelloWorld s’invoque sans paramètres (décrit par l’élément HelloWorld), et retourne un HelloWorldResult de type String (décrit par l’élément HelloWorldResponse).

<s:element name="HelloWorld">
<s:complexType />
</s:element>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>

- Whois s’invoque en passant un objet et retourne un WhoisResult de type String.

L’objet passé se compose de trois attributs : servername de type String, port qui est un entier non signé, et domain de type String.

<s:element name="Whois">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="servername" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="port" type="s:unsignedByte" />
<s:element minOccurs="0" maxOccurs="1" name="domain" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="WhoisResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="WhoisResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>

Il faudra donc une classe PHP représentant cet objet. Ensuite on va utiliser un SoapClient en mode WSDL. Le script qui suit affiche la liste des fonctionnalités du service grâce à la fonction __getFunctions(), puis invoque successivement les deux méthodes du service.

<?php

class Whois
{
private $servername;
private $port;
private $domain;

function __construct($s, $p, $d)
{
$this->servername = $s;
$this->port = $p;
$this->domain = $d;
}
}

try
{
$client = new SoapClient('http://www.ecubicle.net/whois_service.asmx?WSDL');

var_dump($client->__getFunctions());
echo '<hr /><br />';

echo '<b>Invocation de HelloWorld() :</b>';
echo '<br />';

$ret = $client->__soapCall('HelloWorld', array());

print_r($ret);
echo '<br />';
echo $ret->HelloWorldResult;

echo '<br /><br />
<b>Invocation de Whois() :</b>'
;
echo '<br />';
$ret = $client->__soapCall('Whois', array('Whois'=>new Whois('whois.verisign-grs.com',43,'google.fr')));

echo $ret->WhoisResult;
}
catch(Exception $e)
{
echo '<br /><hr />';
echo "<b>Exception:</b> " . $e;
}

?>
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Twitter
  • Google Bookmarks
  • FriendFeed
  • LinkedIn
  • MySpace
  • Netvibes
  • PDF
  • Ping.fm
  • RSS
  • Technorati
  • viadeo FR
  • Wikio
  • Yahoo! Buzz

Related Posts

Cet article a été publié dans Ancien blog avec les mots-clefs : , , , . Bookmarker le permalien. Les commentaires et les trackbacks sont fermés.

3 commentaires

  1. bobabar
    Le 1 octobre 2010 à 14 h 45 min | Permalien

    Bonjour. Dans le cas du service « Whois » (avec descriptif WSDL), je ne comprends pas les paramètres ‘uri’ et ‘location’ ( ‘uri’ => ‘http://monserveur/ws/mon_premier_webservice.php',
    ‘location’ => ‘http://monserveur/ws/mon_premier_webservice.php‘) du client SOAP (SoapClient).

    Et que contient le script « mon_premier_webservice.php » ?

  2. ET
    Le 25 janvier 2011 à 13 h 09 min | Permalien

    Bonjour, je suis de la vieille école procédurale et découvre cette notion de classes et webservices. Merci pour ce post. Si j’ai bien compris tout cela affiche au final « Hello World » ? J’ai pour le coup du mal avoir l’intérêt et la différence avec un simple echo ? Quel est le véritable intérêt en somme ? Merci d’éclairer ma lanterne svp…ET.

  3. Le 10 juin 2011 à 16 h 52 min | Permalien

    @ET
    Le véritable intérêt des webservices est de permettre d’instancier des objets avec des classes à distance via SOAP quelque soit le langage que vous utilisez : votre webservice (en php dans l’exemple) peut être invoqué dans un site web php, asp.net, java, même depuis une animation flash… et même depuis une application car la majorité des langages permettent de faire des clients SOAP. C’est simplement une norme… qui fait gagner un temps fou et permet l’interopérabilité.

    Par contre, c’est très pénible de coder un webservice en PHP, notamment à cause du wdsl, le zend framework pallie quelque peu à ce handicap.