Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > XML
XML Forum d'entraide sur XML avec PHP. Exemples : SimpleXML, OpenXML... Avant de poster -> FAQ XML, Cours XML et Sources XML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/04/2008, 15h54   #1
ovh
Rédacteur
 
Avatar de ovh
 
Homme
Ingénieur développement logiciels
Inscription : mai 2002
Messages : 3 725
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : mai 2002
Messages : 3 725
Points : 6 310
Points : 6 310
Par défaut [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 :
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 :
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 :
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...

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 !
ovh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/04/2008, 20h30   #2
ovh
Rédacteur
 
Avatar de ovh
 
Homme
Ingénieur développement logiciels
Inscription : mai 2002
Messages : 3 725
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : mai 2002
Messages : 3 725
Points : 6 310
Points : 6 310
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...

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 !
ovh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 13h17   #3
ovh
Rédacteur
 
Avatar de ovh
 
Homme
Ingénieur développement logiciels
Inscription : mai 2002
Messages : 3 725
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : mai 2002
Messages : 3 725
Points : 6 310
Points : 6 310
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 :
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 :
<?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 :
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...

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 !
ovh est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h58.


 
 
 
 
Partenaires

Hébergement Web