Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > Services Web
Services Web Forum d'entraide pour les services Web en PHP, qui permettent de créer et de consommer facilement des webservices (génération de WSDL etc.). Exemples : SOAP, NuSOAP, REST, SCA-SDO... Avant de poster -> Cours webservices
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 07/01/2011, 12h32   #1
Membre éclairé
 
Avatar de Satch
 
Inscription : mars 2004
Messages : 448
Détails du profil
Informations personnelles :
Âge : 30

Informations forums :
Inscription : mars 2004
Messages : 448
Points : 381
Points : 381
Envoyer un message via MSN à Satch
Par défaut [SOAP]Retour d'appel à un web service pouvant contenir 0, 1, ou n éléments

Bonjour,
Je sèche depuis quelques heures sur un problème dont je commence à me demander s'il a une solution simple...

J'ai réduit le problème à son plus simple appareil :

Un web service qui me renvoie une entreprise avec un certain nombre d'employé.

Ce web service me renvoie ceci :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
<Entreprise>
  <Nom>entreprise</Nom>
  <Employes>
    <Employe>
      <Nom>nomEmployé 0</Nom>
      <Prenom>prenomEmploye 0</Prenom>
    </Employe>
    <Employe>
      <Nom>nomEmployé 1</Nom>
      <Prenom>prenomEmploye 1</Prenom>
    </Employe>
  </Employes>
</Entreprise>
Lorsqu'il y a plusieurs employés, je peux en parcourir la liste de cette manière :
Code :
1
2
3
4
5
6
7
8
9
	$client = new SoapClient("http://localhost/ws/EntrepriseService.asmx?wsdl");
	$parametres = array('nombreEmployes'=>2);
 
	$ret=$client->__soapCall('GetEntrepriseAvecEmployes', array($parametres));
	$entreprise = $ret->GetEntrepriseAvecEmployesResult;
 
	foreach ($entreprise->Employes->Employe as $employe) {
		echo $employe->Nom;
	}
Par contre s'il n'y a qu'un seul employé le bout de code ci dessus ne fonctionne plus.
je suis obligé de faire $entreprise->Employes au lieu de $entreprise->Employes->Employe dans le foreach.

D'après ce que j'en ai compris, lorsque dans l'élément <Employes> il y a plusieurs <Employe> le soapClient créé un tableau avec les éléments dedans, mais pas dans le cas ou il n'y en a qu'un seul. Dans ce cas, il renvoie l'élément directement.

Y a-t-il un moyen simple de contourner ça ??


PS : le WSLD, au cas ou
Code :
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
      <s:element name="GetEntrepriseAvecEmployes">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="nombreEmployes" type="s:int" />
          </s:sequence>
        </s:complexType>
 
      </s:element>
      <s:element name="GetEntrepriseAvecEmployesResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetEntrepriseAvecEmployesResult" type="tns:Entreprise" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="Entreprise">
 
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Nom" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Employes" type="tns:ArrayOfEmploye" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="ArrayOfEmploye">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="Employe" nillable="true" type="tns:Employe" />
        </s:sequence>
 
      </s:complexType>
      <s:complexType name="Employe">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Nom" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Prenom" type="s:string" />
        </s:sequence>
      </s:complexType>
    </s:schema>
  </wsdl:types>
 
  <wsdl:message name="GetEntrepriseAvecEmployesSoapIn">
    <wsdl:part name="parameters" element="tns:GetEntrepriseAvecEmployes" />
  </wsdl:message>
  <wsdl:message name="GetEntrepriseAvecEmployesSoapOut">
    <wsdl:part name="parameters" element="tns:GetEntrepriseAvecEmployesResponse" />
  </wsdl:message>
  <wsdl:portType name="EntrepriseServiceSoap">
    <wsdl:operation name="GetEntrepriseAvecEmployes">
      <wsdl:input message="tns:GetEntrepriseAvecEmployesSoapIn" />
 
      <wsdl:output message="tns:GetEntrepriseAvecEmployesSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="EntrepriseServiceSoap" type="tns:EntrepriseServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetEntrepriseAvecEmployes">
      <soap:operation soapAction="http://tempuri.org/GetEntrepriseAvecEmployes" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
 
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="EntrepriseServiceSoap12" type="tns:EntrepriseServiceSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetEntrepriseAvecEmployes">
 
      <soap12:operation soapAction="http://tempuri.org/GetEntrepriseAvecEmployes" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
 
  <wsdl:service name="EntrepriseService">
    <wsdl:port name="EntrepriseServiceSoap" binding="tns:EntrepriseServiceSoap">
      <soap:address location="http://localhost/ws/EntrepriseService.asmx" />
    </wsdl:port>
    <wsdl:port name="EntrepriseServiceSoap12" binding="tns:EntrepriseServiceSoap12">
      <soap12:address location="http://localhost/ws/EntrepriseService.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
__________________
Je sais que désormais vivre est un calembour,
La mort est devenue un état permanent,
Le monde est aux fantômes, aux hyènes et aux vautours.
Moi je vous dis bravo et vive la mort.
Satch est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 09h25   #2
Invité de passage
 
Inscription : janvier 2011
Messages : 3
Détails du profil
Informations forums :
Inscription : janvier 2011
Messages : 3
Points : 1
Points : 1
Moi j'ai contourné le problème comme cela :

Code :
1
2
3
4
5
6
7
8
9
10
11
 
	$client = new SoapClient("http://localhost/ws/EntrepriseService.asmx?wsdl");
	$parametres = array('nombreEmployes'=>2);
 
	$ret=$client->__soapCall('GetEntrepriseAvecEmployes', array($parametres));
	$entreprise = $ret->GetEntrepriseAvecEmployesResult;
 
	if (!is_array($entreprise->Employes->Employe)) $entreprise->Employes->Employe = array($entreprise->Employes->Employe);
	foreach ($entreprise->Employes->Employe as $employe) {
		echo $employe->Nom;
	}
Dadouduck est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2011, 13h48   #3
Membre éclairé
 
Avatar de Satch
 
Inscription : mars 2004
Messages : 448
Détails du profil
Informations personnelles :
Âge : 30

Informations forums :
Inscription : mars 2004
Messages : 448
Points : 381
Points : 381
Envoyer un message via MSN à Satch
Merci pour la réponse.
Ca me dérangeait de faire des if à tout bout de champ, mais j'ai en gros fait la même chose.

J'ai pris un petit outil (wsdl2php) qui génère des classes php à partir du wsdl et l'ai modifié pour que une fonction toArray() soit incluse dans les objets problématiques.

ça fonctionne à merveille maintenant.

Mais bon, c'est quand même assez space que le soap de PHP fasse un objet ou un tableau d'objet suivant qu'il y ait un ou plusieurs éléments. Je ne trouve pas ça normal...

quand on a :
Code :
 <s:element minOccurs="0" maxOccurs="unbounded" name="Employe" nillable="true" type="tns:Employe" />
pour moi il est clair qu'un tableau DOIT être retourné, peu importe le nombre d'employés.
Mais ce n'est malheureusement pas le cas.

En tous cas ça m'a rappelé pourquoi j'évitais de faire du PHP...
__________________
Je sais que désormais vivre est un calembour,
La mort est devenue un état permanent,
Le monde est aux fantômes, aux hyènes et aux vautours.
Moi je vous dis bravo et vive la mort.
Satch est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h43.


 
 
 
 
Partenaires

Hébergement Web