Bon, ça marche plus ou moins... Désolé de le dire, mais la gestion de soap est vraiment mal foutue dès qu'on veut faire quelque chose de non trivial...
Je suis parvenu à générer du XML en modifiant ceci dans mon WSDL :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:toto">
<xsd:element name="XmlResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="1" name="XmlResult">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:any/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="getBCCInfoResponse">
<part name="return" type="typens:XmlResponse" />
</message> |
Ca a l'air compliqué, ça l'est , mais c'est parce que j'ai copié-collé un WSDL issu d'un webservice opérationnel en .NET et que je parviens à exploiter sans problème avec un client PHP.
Je construis ensuite mon objet à l'aide de la classe SimpleXMLElement, et je retourne donc tel quel. J'obtiens bien une réponse SOAP correctement formée cette fois :
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><SOAP-ENV:getBCCInfoResponse><return><commande><ref>280556</ref><acompte>426</acompte><detail><produit><SOAP-ENC:Struct><pid>131210</pid><prix>22</prix><quant>1</quant></SOAP-ENC:Struct><SOAP-ENC:Struct><pid>124590</pid><prix>102.02</prix><quant>1</quant></SOAP-ENC:Struct><SOAP-ENC:Struct><pid>134922</pid><prix>206.99</prix><quant>1</quant></SOAP-ENC:Struct><SOAP-ENC:Struct><pid>128488</pid><prix>95</prix><quant>1</quant></SOAP-ENC:Struct></produit></detail><prixtot>426.01</prixtot></commande></return></SOAP-ENV:getBCCInfoResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
enfin presque...
Il me pourrit le code avec des SOAP-ENC:Struct qui viennent de je ne sais où...
Le client PHP :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ini_set("soap.wsdl_cache_enabled", "0");
$soap = new SoapClient("http://.../webservice.wsdl", array("trace" => true));
try {
$result = $soap->getBCCInfo('123456'); // ref de test
$xmlsoap = $soap->__getLastResponse();
echo "<p>réponse soap = ".htmlentities($xmlsoap)."</p>";
}
catch (Exception $e) {
echo '<p class="cadrewarning">Erreur : '.$e->getMessage().'</p>';
}
$commande = $result->commande;
if ($commande) {
echo "<p>Commande numéro <b>".$commande->ref."</b> :<br>";
echo "Acompte : ".sprintf("%01.2f", $commande->acompte)." €<br>";
echo "Reste à payer : ".sprintf("%01.2f", $commande->prixtot - $commande->acompte)."</p>";
foreach ($commande->detail->produit->Struct as $prod) {
echo $prod->pid." -desc- p=".$prod->prix.", q=".$prod->quant."<br>";
}
} |
Ca marche. MAIS ! Ce n'est pas un objet SimpleXML que j'ai, mais un simple stdClass... De plus, j'ai ces fameux "Struct" parasites qui pourrissent un peu le code du foreach.
Enfin, j'ai des doutes sur l'interopérabilité du brol... (quid si j'interroge ce serveur soap avec un client .NET par exemple ? )
Quand je pense qu'à partir d'un webservice écrit en .NET, le client php soap me renvoit le xml sous forme d'une chaîne de caractère, que je n'ai plus qu'à charger avec simplexml_load_string(), c'est si simple...
Et ici, en utilisant le même langage (PHP), pour faire la partie serveur, c'est si laborieux !!!
Partager