IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques et frameworks PHP Discussion :

[XML] [SOAP] [PHP5] Développement d'un webservice : comment renvoyer du XML ?


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    ovh
    ovh est déconnecté
    Rédacteur
    Avatar de ovh
    Homme Profil pro
    Architecte devops web full stack
    Inscrit en
    Mai 2002
    Messages
    3 841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte devops web full stack

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 841
    Points : 6 514
    Points
    6 514
    Par défaut [XML] [SOAP] [PHP5] Développement d'un webservice : comment renvoyer du XML ?
    Bonjour à tous

    J'ai déjà développé un webservice soap basique en PHP5, en ce sens que ma fonction retourne un objet simple de type xsd:string.

    Maintenant j'ai besoin de retourner des données étendues, sous forme XML. Je m'étais naïvement dit que le xml étant du texte, je pouvais le faire contenir dans un type xsd:string... Hé bien non : PHP fait automatiquement un htmlentities() sur le code xml, résultat, ma requête soap est inexploitable

    Mon WSDL (fait à la main puisque PHP ne propose aucune génération automatique ) :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    <?xml version="1.0" encoding="iso-8859-1" ?>
     
    <!-- partie 1 : Definitions -->
    <definitions name="toto" 
    		targetNamespace="urn:toto" 
    		xmlns:typens="urn:toto" 
    		xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    		xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    		xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    		xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    		xmlns="http://schemas.xmlsoap.org/wsdl/">
     
    	<!-- partie 2 : Types -->
     
     <types>
        	<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" 
    			targetNamespace="urn:toto">
     	</xsd:schema>
     </types> 
     
     
    	<!-- partie 3 : Message -->
    	<message name="getBCCInfoRequest">
    		<part name="ref" type="xsd:string" />
    	</message>
    	<message name="getBCCInfoResponse">
    		<part name="return" type="xsd:string" />
    	</message>
     
    	<!-- partie 4 : Port Type -->
    	<portType name="totoPort">
    		<!-- partie 5 : Operation -->
    		<operation name="getBCCInfo">
    			<input message="typens:getBCCInfoRequest"/>
    			<output message="typens:getBCCInfoResponse"/>
    		</operation>
    	</portType>
     
    	<!-- partie 6 : Binding -->
    	<binding name="totoBinding" type="typens:totoPort">
    		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    		<operation name="getBCCInfo">
    			<soap:operation soapAction="totoAction"/>
    			<input name="getBCCInfoRequest">
    				<soap:body use="encoded" 	
    						namespace="urn:toto" 	
    						encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    			</input>
    			<output name="getBCCInfoResponse">
    				<soap:body use="literal" />
    			</output>
    		</operation>
    	</binding>
     
    	<!-- partie 7 : Service -->
    	<service name="totoService">
    		<documentation>toto Intranet WebService. Contact webmaster for more information.</documentation>
    		<!-- partie 8 : Port -->
    		<port name="totoPort" binding="typens:totoBinding">
    			<soap:address location="http://dev.toto.be/soap/webservice.php"/>
    		</port>
    	</service>
    </definitions>

    Le code de mon serveur soap, simpliste, pour test :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ini_set("soap.wsdl_cache_enabled", "0");
    $srvsoap = new SoapServer('webservice.wsdl');
    $srvsoap->addFunction('getBCCInfo');
     if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    	$srvsoap->handle();
    }
     
    function getBCCInfo($ref) {
    	$xmltxt = '<commande><ref>'.$ref.'</ref><acompte>123.45</acompte></commande>';
    	return $xmltxt;
    }

    Le retour SOAP :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:getBCCInfoResponse><return>&lt;commande&gt;&lt;ref&gt;ttata&lt;/ref&gt;&lt;acompte&gt;123.45&lt;/acompte&gt;&lt;/commande&gt;</return></SOAP-ENV:getBCCInfoResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Sans ces &lt; et &gt; tout fonctionnerait merveilleusement bien...

    Comment faire ? Probablement en modifiant le WSDL, mais je ne vois pas comment, j'ai essayé de plein de manière différente, en faisant un type personnalisé, j'ai précisé que le soap:body ne devait pas être encodé (use="literal"), j'ai tenté de passer un objet SimpleXMLElement à la place d'un texte, mais rien n'y fait...

    pour toute aide

    Tutoriels sur les UPS, e-commerce, PHP, critiques de livres...

    Pensez à consulter les FAQs et les cours et tutoriels.
    FAQ Linux - Cours et tutoriels Linux - FAQ PHP - Cours et tutoriels PHP
    Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles.

    Je n'ai rien à voir avec la société www.ovh.com !

  2. #2
    ovh
    ovh est déconnecté
    Rédacteur
    Avatar de ovh
    Homme Profil pro
    Architecte devops web full stack
    Inscrit en
    Mai 2002
    Messages
    3 841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte devops web full stack

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 841
    Points : 6 514
    Points
    6 514
    Par défaut
    Ca y est j'ai trouvé une solution en fin de journée, en me basant sur un wsdl d'un de mes fournisseurs, réalisé en .NET et en utilisant un objet SimpleXMLElement directement, c'est PHP qui le convertira en balises xml comme il faut.

    Je poste le détail demain, quand je reprendrai tout ça à tête reposée pour avoir un code propre

    Tutoriels sur les UPS, e-commerce, PHP, critiques de livres...

    Pensez à consulter les FAQs et les cours et tutoriels.
    FAQ Linux - Cours et tutoriels Linux - FAQ PHP - Cours et tutoriels PHP
    Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles.

    Je n'ai rien à voir avec la société www.ovh.com !

  3. #3
    ovh
    ovh est déconnecté
    Rédacteur
    Avatar de ovh
    Homme Profil pro
    Architecte devops web full stack
    Inscrit en
    Mai 2002
    Messages
    3 841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte devops web full stack

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 841
    Points : 6 514
    Points
    6 514
    Par défaut
    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 :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    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 :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <?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 :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    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)." &euro;<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 !!!

    Tutoriels sur les UPS, e-commerce, PHP, critiques de livres...

    Pensez à consulter les FAQs et les cours et tutoriels.
    FAQ Linux - Cours et tutoriels Linux - FAQ PHP - Cours et tutoriels PHP
    Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles.

    Je n'ai rien à voir avec la société www.ovh.com !

Discussions similaires

  1. [WD15] Webservice: comment renvoyer 2 parametres
    Par GEOFDEN dans le forum WinDev
    Réponses: 4
    Dernier message: 03/02/2011, 17h10
  2. [Web Service][SOAP] Comment activer l'extension soap (php5) ?
    Par lauryk dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 13/09/2007, 11h57
  3. [Web Service][SOAP] PHP5 SOAP et header
    Par ckeromen dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 18/12/2006, 20h27
  4. [Web Service][SOAP] Webservices : Comment faire ?
    Par juliotte dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 18/12/2006, 16h50
  5. [Directives] [PHP5.1.1][HTTPD2.2] Comment autoriser les php_flags ?
    Par frochard dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 24/12/2005, 23h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo