Aujourd'hui, j'ai reçu sur mon blogue un commentaire anonyme concernant l'article que j'ai écrit le 21 mai dernier intitulé "Créer un WSDL facilement avec Zend Framework". J'ai été un peu surpris par les propos de l'auteur, légèrement agressif, qui ne m'a laissé aucun moyen de le rejoindre directement (aucun nom ni courriel). Autrement, je l'aurais invité à m'envoyer son code et j'aurais été heureux de l'aider car l'exemple que j'avais publié provenait d'un cas réel que j'utilise dans un de mes projets.
Plutôt que d'approuver son commentaire, j'ai décidé de le publier ici et d'y consacrer ma chronique quotidienne. En guise d'introduction, voici le texte intégral:
dsl de te decevoir mais ton machin marche pas!!!!!
J'ai retourné le serveur dans tous les sens, rien à faire j'avais le message : "Couldn't load from...". C'est uniquement quand j'ai enlevé la condition 'if'-'else- que j'ai pu avoir le WSDL.
Quant au client il a l'air simple mais ne fonctionne pas non plus. désolé...
Le titre est attrayant les commentaires bien réalisés mais le résultat est insatisfaisant.
OK, c'est possible que j'aie fait une erreur, elle est humaine. J'ai peut-être mal expliqué un détail ? Ou fait une gaffe en recopiant le code ? Pourtant, je viens de le tester à nouveau et ça marche très bien. Et ça se peut que le programmeur en question ait fait un code 18. Tout porte à croire que c'est le cas.
La preuve est que j'ai su reproduire le bogue en moins d'une minute en introduisant volontairement une erreur d'implémentation. Le message obtenu se trouve dans le tag faultstring du XML et affiche quelque chose qui ressemble à ceci :
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/WSDL/service.php?wsdl' : failed to load external entity "http://localhost/WSDL/service.php?wsdl"
Que nous dit cette notice ? Que le service web ne se charge pas correctement. Et si du côté serveur ça ne fonctionne pas, ce n'est pas surprenant que le client n'ait pas plus de succès. Il faut régler le problème à la source.
Une des causes possibles est que "localhost" n'ait pas été modifié pour rediriger vers son propre domaine. Il faut comprendre que mon code est sur mon propre serveur de développement hébergé sur ma machine (127.0.0.1), donc j'utilise localhost pour ma démo. Une autre possibilité est que son service web ne soit pas hébergé dans un répertoire du même nom que le mien ou que le fichier n'ait pas le bon nom.
Si on jete un oeil au code du fichier service.php, le IF/ELSE sert à deux choses. D'abord à générer la définition du WSDL en mode AutoDiscover (lorsqu'on lui passe en query string le paramètre "wsdl"), sinon à prendre en charge les demandes des clients. Donc le même fichier est réutilisé pour deux comportements différents au lieu de séparer le code en deux fichiers PHP sur le disque.
C'est important aussi de remarquer que dans le ELSE, l'objet Zend_Soap_Server prend en paramètre l'URL de la définition du service web, donc le fichier service.php AVEC le paramètre "wsdl". Si on ne fournit pas l'URL correctement ou si on omet de mettre le paramètre wsdl (celui détecté par le $_GET['wsdl'], le message "Couldn't load from 'url'" apparaît. Au moment de prendre en charge la requête du client, le fichier s'appelle lui-même en réclamant la définition pour instancier Zend_Soap_Server.
En résumé :
- L'accès à la page service.php?wsdl affichera le XML de la définition du service
- L'accès direct à la page service.php (sans ?wsdl) devrait faire afficher un faultstring Invalid XML car aucune requête à une fonction n'est faite
- Le client doit appeler le WSDL en utilisant l'URL complet "http://votre-serveur/service.php?wsdl". Ceci a pour effet d'interroger le service pour savoir quelles fonctions il peut appeler.
Même en présentant un code fonctionnel dans sa plus simple expression, son exécution a affiché une erreur explicite et le programmeur n'a pas su chercher la solution au bon endroit. Pourtant, ce n'est que quelques lignes de code, alors nul besoin de retourner le serveur dans tous les sens ;-)
Ce blog est tout bonnement brillant.
Il fait partie de mon top 10.
Alors inutile de s'attarder sur qq boulets aussi agressifs qu'ignares.
Félicitations et Bonne continuation.
Merci Laurent, c'est apprécié. Ceci dit, ça me fera toujours plaisir de répondre aux questions et de donner un coup de main aux programmeurs s'ils rencontrent des problèmes :-)
En effet,
Je partage largement votre point de vue sur la quantité de personnes qui utilisent sans modération copier/coller, même au sein de structures réputées sérieuses (SSII, webagencies, etc.) !
Le plus insupportable est encore l'arrogance de leur ignorance !
bonjour, alors voila j'ai développer un site en php qui utilise des webs services via soap. Sur ma machine de test tout fonctionne parfairtement, mais une fois en prod j'obtiens des erreurs SOAP de ce type:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'nom du serveur?wsdl' : failed to load external entity "nom du serveur?wsdl"
le module SOAP est bien activé sur le serveur apache et libxml de même...
problème résolut, une ligne dans le fichier hosts donnait comme résolution du nom de domaine de la machine son ip privée. Comme la machine qui héberge les web services héberge également le site cela ne pouvait pas fonctionner...
Tant mieux si tu as résolu ton problème :)