skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

jeudi 21 mai 2009

Créer un WSDL facilement avec Zend Framework

Publié par Infinite Loop, à 22 h 35 18 commentaires

Par le passé, je dois avouer avoir fait une tentative, une seule, pour créer à la main un fichier WSDL (Web Services Description Language) et je me suis promis que plus jamais je ne voulais revivre cette expérience. Certains outils existent pour automatiser cette pénible tâche et ceux que j'avais testé jusqu'à maintenant généraient un fichier .wsdl statique.

Pour expliquer simplement, un fichier WSDL comprend une structure XML qui définit les fonctions accessibles par le service, ses paramètres, les types et ce qui est retourné. Lorsque le comportement d'une des fonctions du service web change, on est obligé soit de modifier à la main la description, soit de regénérer le fichier WSDL et le redéposer sur le serveur.

Jusqu'à ce qu'on découvre l'objet Zend_Soap_AutoDiscover du Zend Framework. Sa force : être en mesure d'inspecter une classe au runtime et de générer à la volée le fichier WSDL correspondant.

Voici un petit tutoriel pour créer un premier service web, réduit à sa plus simple expression. J'offrirai le service de retourner le pourcentage de taxe associé au nom envoyé par le client.

1. Créer une classe qui offrira les services

Ici, ça peut être n'importe quelle classe, pas nécessairement une construite spécifiquement pour le service web. Une seule condition doit être respectée : suivre le format de documentation des docblocks car AutoDiscover se base sur commentaires pour construire la description WSDL.

Chaque fonction de la classe doit être précédée d'un docblock qui doit suivre la syntaxe suivante :

  • @param type param_name
  • @return type
Comme dans l'exemple ci-dessous :
// Ex: fichier "tax.class.php"

class Tax {

/**
* Return tax value
* @param string $type
* @return float
*/
public function getTaxValue($type = 'TPS'){
// récupérer les taxes d'une quelconque façon,
// par exemple d'une base de données

// Taxe sur les Produits et Services
if($type == 'TPS'){
return 5.0;
}
// Taxe de Vente du Québec
elseif ($type == 'TVQ'){
return 7.5;
}
else {
return 0;
}

}
}
Si vous rencontrez l'erreur "Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Missing <message>...", c'est probablement que votre docblock est mal structuré. Le commentaire doit absolument débuter par /**, avec deux astérisques (dans Eclipse, vous devriez voir une différence dans la coloration syntaxique).

2. Manipuler les requêtes du côté serveur

Comme c'est vous qui offrez un service, vous devrez préparer une page qui effectuera les manipulations des requêtes clients. Ce fichier aura deux utilités :
  • retourner la description du WSDL lorsqu'un paramètre sera passé
  • traiter la demande
// Ex: fichier "service.php"

require_once('Zend/Soap/AutoDiscover.php');
require_once('Zend/Soap/Server.php');
require_once('tax.class.php');

if(isset($_GET['wsdl'])){
// inspecter la classe Tax et retourner la description
$wsdl = new Zend_Soap_AutoDiscover();
$wsdl->setClass('Tax');
$wsdl->handle();
}
else{
// traitement
$server = new Zend_Soap_Server('http://localhost/WSDL/service.php?wsdl');
$server->setClass('Tax');
$server->handle();
}
Si l'erreur suivante se produit "Fatal error: Uncaught exception 'Zend_Soap_Server_Exception' with message 'SOAP extension is not loaded.'", c'est que l'objet Zend_Soap_Server utilise l'extension php_soap.so (ou .dll). Activez la dans php.ini.

Vous êtes maintenant prêts à fournir les taux de taxes.

3. Créer une requête en tant que client

Probablement qu'en temps normal, ce ne sera pas vous qui utiliserez votre service web mais mieux vaut le tester avant de l'offrir à vos clients. Ceux-ci pourront utiliser le langage de leur choix pour faire appel à votre service, mais nous, comme nous utilisons déjà le Zend Framework, nous allons nous servir d'un autre objet au nom évocateur de Zend_Soap_Client. Cet objet peut aussi être utilisé lorsque vous voudrez vous-même utiliser un service offert par un autre fournisseur. Rappelez-vous que du point de vue du client, il ne voit pas que c'est programmé en PHP, ils ne voient que la définition WSDL pour pouvoir communiquer avec lui.

Une fois la connection établie, le client peut appeler les fonctions comme un objet. Ici, il aura accès à la fonction getTaxValue.
// Ex: fichier "appel.php"

require_once('Zend/Soap/Client.php');

try {
$client = new Zend_Soap_Client('http://localhost/WSDL/service.php?wsdl');

echo 'La TPS est de : ' . $client->getTaxValue('TPS') . ' %';
echo 'La TVQ est de : ' . $client->getTaxValue('TVQ') . ' %';
}
catch(Zend_Exception $e){
echo $e->getMessage();
}
Ce qui devrait afficher ceci :
La TPS est de : 5 %
La TVQ est de : 7.5 %


Tags: PHP, Zend Framework

18 réponses à "Créer un WSDL facilement avec Zend Framework"

  1. Unknown a dit...
    13 novembre 2009 à 16 h 18

    excellent article.

    Par contre dans la partie client, il est inutile de faire un include tax.class.php. Cette class est seulement côté server.

    @++

    Infinite Loop a dit...
    13 novembre 2009 à 16 h 19

    Oups, tu as raison!

    Anonyme a dit...
    22 mars 2010 à 10 h 36

    ça fonctionne nickel.
    C'est simple. C'est ludique.

    Je dis bravo et merci (je vais pouvoir aborder sereinement soap sur mon projet)

    Vlad

    Anonyme a dit...
    24 mars 2011 à 12 h 30

    Bonjour, lorsque je fais tourner votre code g un message d'erreur dont je n'arrives pas à identifier la cause. Auriez-vous une idée pour m'orienter?

    Merci.
    Claude
    ---------------> erreur:

    Exception information:

    Message: Wrong Version
    Stack trace:

    #0 /var/www/virgox/library/Zend/Soap/Client.php(1113): SoapClient->__soapCall('getTaxValue', Array, NULL, NULL, Array)
    #1 /var/www/virgox/application/modules/default/controllers/IndexController.php(35): Zend_Soap_Client->__call('getTaxValue', Array)
    #2 /var/www/virgox/application/modules/default/controllers/IndexController.php(35): Zend_Soap_Client->getTaxValue('TPS')
    #3 /var/www/virgox/library/Zend/Controller/Action.php(513): IndexController->cliAction()
    #4 /var/www/virgox/library/Zend/Controller/Dispatcher/Standard.php(289): Zend_Controller_Action->dispatch('cliAction')
    #5 /var/www/virgox/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
    #6 /var/www/virgox/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch()
    #7 /var/www/virgox/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
    #8 /var/www/virgox/public/index.php(50): Zend_Application->run()
    #9 {main}

    Request Parameters:

    array (
    'controller' => 'index',
    'action' => 'cli',
    'module' => 'default',
    )

    Anonyme a dit...
    25 mars 2011 à 06 h 01

    ...suite...

    je pense que c'est lié au cache. G l'impression que les dernières modifs du wsdl lorsque je modifie la classe de service (Tax) ne sont pas prises immédiatement en compte. Le lendemain cela fonctionnait.

    Merci.
    Claude

    Infinite Loop a dit...
    25 mars 2011 à 06 h 47

    Tant mieux si c'était lié au cache, ça doit dépendre du setup de chaque serveur.

    Anonyme a dit...
    6 décembre 2011 à 11 h 59

    Bonjour,

    le fichier service.php fait il partie de Zend ? Je ne le trouve nulle part et il n'est a priori pas expliqué. Hors tout le problème que je rencontre avec SOAP c'est la génération du fichier WSDL

    A+

    Infinite Loop a dit...
    6 décembre 2011 à 13 h 03

    Le fichier service.php, c'est l'équivalent du contenu qui est expliqué au point 2.

    Anonyme a dit...
    7 décembre 2011 à 04 h 36

    OK, je voulais absolument qu'il y ait un serveur.php...

    Merci pour la réponse, ça fonctionne.

    Anonyme a dit...
    25 janvier 2012 à 08 h 06

    S'il vous plait,
    Est que je peux avoir les noms de chaque fichiers, et comment les utiliser
    Merci beaucoup pour votre aide

    Infinite Loop a dit...
    26 janvier 2012 à 06 h 57

    Bien sûr. À titre d'exemple, j'ai ajouté des noms génériques : tax.class.php, service.php et appel.php.

    Anonyme a dit...
    27 janvier 2012 à 02 h 29

    Bonjour,

    Ça fait maintenant un moment que j'utilise ce système (qui fonctionne très bien en PHP). Mais je suis confronté maintenant à un nouveau problème.

    Je tente de créer un client ASP (classic) mais le format WSDL de Zend_Soap_AutoDiscover n'est pas reconnu.

    En effet, le format du fichier WSDL pour l'ASP est différent du celui généré par Zend_Soap_AutoDiscover.

    exemple : http://ws.textanywhere.net/ta_SMS.asmx?wsdl

    Ma question est la suivant : avec Zend_Soap_AutoDiscover, peut-on créer ce genre de format ? pour que mon WebService PHP puisse etre lu par le PHP et l'ASP ??

    Merci.

    Olivier

    Infinite Loop a dit...
    27 janvier 2012 à 06 h 55

    Salut Olivier, je n'ai jamais travaillé avec un client SOAP à partir d'ASP classique. Mais je soupçonne que c'est la version de SOAP qui cause problème. Le standard actuel est 1.2 (par défaut dans Zend mais tu peux le faire basculer à 1.1). Tu pourrais regarder comment est fait l'implémentation de la portion client en PHP et tenter de le reproduire en ASP.

    $url = 'http://abc.com/somservice.asmx?wsdl';
    $options = array("soap_version" => SOAP_1_1);
    $client = new Zend_Soap_Client($url,$options);

    Exemple tiré d'ici.

    Anonyme a dit...
    27 janvier 2012 à 13 h 50

    Salut, Et merci pour ta réponse.

    Niveau Client, je sais qu'on peut spécifier la version. Mais comment déterminer la version de mon fichier WSDL ?

    Merci

    Olivier

    thierry a dit...
    12 mars 2012 à 11 h 12

    Bonjour

    Article très intéressant :)

    Petite question : vous utilisez un chemin relatif commencant par Zend/ dans vos includes. Soit! j'adapte mon chemin relatif en conséquence mais je tombe sur une erreur identique à l'intérieur même des classes du framework.

    Dois-je modifier l'ensemble des classes du framework comme je l'ai fait avec mon service ? ou y-a-t-il une astuce dont je n'aurais pas connaissance ?

    thierry a dit...
    13 mars 2012 à 06 h 15

    après moultes recherches ces dernières 48h, j'ai enfin trouvé la réponse à mon problème ...

    pour ceux qui se poseraient la même question que moi ("Il n'y a pas de question idiote, seulement une réponse idiote" Albert Einstein),
    voici la solution :

    Au début du document racine, ajouter cette instruction
    set_include_path('.' . PATH_SEPARATOR . 'E:/ZF/library' . PATH_SEPARATOR . get_include_path());

    A quoi cela correspond ?
    En fait, on inclue dans les chemins de recherche par défaut le répertoire courant ('.'), le répertoire contenant les classes Zend ('E:/ZF/library') et on rappelle les chemins par défaut déjà déclarés (get_include_path())

    En espérant avoir été clair pour les débutants Zend comme moi ;)

    Zeine a dit...
    15 juillet 2012 à 14 h 48

    Trop bon votre tutoriel. Depuis hier je me casse le tête sur zend pour produire un webservice. Mon problème est maintenant résolu. Merci !

    Maxor a dit...
    9 avril 2013 à 16 h 45

    Salut Infinite. Très bon tuto. Mon soucis est la fameuse "SOAP-ERROR: Parsing WSDL". Le WSDL s'affiche bien. Je suis en phase de développement en local sous Debian. Que dois-je indiquer dans mon hosts?
    Voici ce que j'ai actuellement: 127.0.1.1 nom_domaine.com alias
    Pour atteindre le soap, je tape l'url:
    nom_domaine.com/webservice/soap.
    Est-ce correct ou dois-je ajouter quelque chose?


Publier un commentaire

Message plus récent Messages plus anciens Accueil
S'abonner à : Publier des commentaires (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (55)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ►  2012 (105)
      • ►  décembre 2012 (8)
      • ►  novembre 2012 (5)
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ►  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ►  octobre 2010 (32)
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ▼  2009 (429)
      • ►  décembre 2009 (32)
      • ►  novembre 2009 (34)
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ►  juin 2009 (38)
      • ▼  mai 2009 (37)
        • Obtenir le Page Rank Google en PHP ou Perl
        • Citation no. 32 sur Windows
        • Google Talk chatback badge
        • Images volantes en JavaScript
        • ASP vs PHP
        • Intervalles de dates sous PostgreSQL et SQL Server
        • Ordre de chargement avec Prototype
        • Pouvez-vous lire ceci ?
        • Service ReCaptcha en français
        • Citation no. 31 sur la lune
        • Google killers
        • Configurer Zend_Tool en CLI
        • Quelques logos intéressants
        • Créer un WSDL facilement avec Zend Framework
        • XSS sur Wikio... et Archambault Musique
        • Encryption de données en PHP
        • Virtualiser les fureteurs avec Xenocode
        • Traductions pour Uploadify
        • Citation no. 30 sur la force
        • ASCII Art avec GIMP
        • Fonction JavaScript à paramètres variables
        • The Mythical Man-Month - Loi de Brooks
        • Fichier en attachement avec Zend_Mail
        • Konami Code sur jQuery et Facebook
        • Star Trek
        • 3 façons de lire du XML en PHP
        • Citation no. 29 sur l'infini
        • Déboguer avec FirePHP
        • 99 bouteilles de bière
        • Étude de cas Zend Solutions
        • Zend_Service_Twitter
        • Devinette mathématique classique
        • Obtenir l'extension d'un fichier
        • Récupérer une image sur Amazon avec Zend Framework
        • Citation no. 28 sur un jour de travail productif
        • Modifier l'entête Server d'Apache
        • Contrôler le téléchargement d'un fichier
      • ►  avril 2009 (35)
      • ►  mars 2009 (36)
      • ►  février 2009 (32)
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft