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 :

[Web Service][SOAP] récupérer les données d'un complexType


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Membre averti
    [Web Service][SOAP] récupérer les données d'un complexType
    Bonjour à tous.

    Alors voilà, cela fait un moment que j'avais essayé de placer des complexType dans mon fichier WSDL, mais je n'avais pas réussi après maintes recherches et tests. J'ai laissé çà de côté, et la comme j'ai un peu de temps je m'y suis remis. Et je n'y arrive toujours pas...
    J'ai compris l'utilité du classmap mais comment bien le manipuler ?
    Citation Envoyé par koopajah
    Le classmap sert a faire un mapping entre les types de ton WSDL et tes classes PHP pour stocker le résultat.
    http://www.developpez.net/forums/sho...light=classmap

    Donc si vous avez un exemple tout simple sous la main, ou un lien vers une doc précise (c'est rare), je suis tout à fait preneur

    Merci pour votre aide.

  2. #2
    Membre expert
    Les documentations sur les wsdl et leur utilisation en PHP ne sont pas monnaie courante (dans d'autres langages non plus d'ailleurs).
    J'ai réussi a faire fonctionner le mien à force de trifouiller le WSDL et le code PHP dans tous les sens jusqu'à ce que ca marche et j'avoue n'avoir pas TOUT compris au pourquoi du comment.

    Dans tous les cas, lorsque ton WSDL passe plus d'un type en paramètre de ton webservice il vaut mieux se créer un type complexe (composé de type simple) et lui associer son équivalent en PHP.

    Récemment j'avais lu une news a propos de WSDL class generator, je ne sais pas du tout ce que ca vaut mais tu peux essayer. Sinon il y a aussi Construire un service web en php 5

    Une chose a bien savoir : commencer avec des choses SIMPLES! Il y a plusieurs problemes possibles : le serveur, le client, le wsdl, les classes php, le classmap. Et il vaut mieux avoir des choses TRES simples pour commencer et les compliquer au fur et a mesure (j'avais tenté un complex type qui était lui meme un tableau de complextype et j'en suis vite revenu a un complex type contenant simplement un int pour débuter)

    Ensuite utilises bien les fonctions conseillées dans le thread que tu cites et qui permettent de savoir ce qui se passe sur le serveur.

  3. #3
    Membre averti
    Je suis déjà allé sur les 2 liens proposés, d'ailleurs le 2eme est très bien il m'a fait comprendre pas mal de choses. Mais dans son exemple il n'y a que un seul element dans son complexType.
    Et sinon je préfère créer moi même le fichier WSDL pour comprendre au maximum, même si ca ressemble plus à du bourrage de crâne par moments

    J'ai déjà un exemple simple qui fonctionne, pour situer un peu, voila un bout de mon WSDL :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
            <wsdl:message name="CreateCustomerRequest">
    		<wsdl:part name="id" 		type="xsd:int"/>
    		<wsdl:part name="lname" 	type="xsd:string"/>
    		<wsdl:part name="fname"		type="xsd:string"/>
    		<wsdl:part name="age"		type="xsd:int"/>
    		<wsdl:part name="tv"		type="xsd:int"/>
    		<wsdl:part name="internet" 	type="xsd:boolean"/>
    		<wsdl:part name="vod"		type="xsd:boolean"/>
    		<wsdl:part name="ppv"		type="xsd:boolean"/>
    		<wsdl:part name="games"		type="xsd:boolean"/>
    		<wsdl:part name="serv"		type="xsd:boolean"/>
    	</wsdl:message>
    	<wsdl:message name="CreateCustomerResponse">
    		<wsdl:part name="return" type="xsd:SOAP-ENC:Array"/>
    	</wsdl:message>

    La fonction CreateCustomer renvoie 2 paramètres, l'id et un code de retour.
    Et comme tu le dis :
    Dans tous les cas, lorsque ton WSDL passe plus d'un type en paramètre de ton webservice il vaut mieux se créer un type complexe (composé de type simple) et lui associer son équivalent en PHP.
    J'aimerais bien faire passer un complexType au lieu de ces 10 paramètres. Même si cela fonctionne ainsi, j'ai envie de comprendre comment ca se passe pour l'associer en PhP. Surtout que j'en aurais surement besoin prochainement.

    En tout cas, je vais reprendre au début, refaire un exemple simple comme tu dis, et je vais voir.


    Et sinon pour ceci ?
    In response to comment by Nathan O'Sullivan about returning (or passing) a complex type, you can also use the stdClass() object.

    Assume you define a complex type like so:

    <xsd:complexType name="TestType">
    <xsd:all>
    <xsd:element name="A" type="xsd:string" />
    <xsd:element name="B" type="xsd:int" />
    <xsd:element name="C" type="xsd:boolean" />
    </xsd:all>
    </xsd:complexType>

    To use an object in place of an array you can do:

    $test = new stdClass();
    $test->A = "test string";
    $test->B = 45;
    $test->C = false;

    $result = $client->Test($test);
    C'est une méthode à la brutale ?

  4. #4
    Membre expert
    Pour ta dernière question je pense que oui, il vaut mieux te créer ta propre classe.

    Extraits de mon WSDL :
    Code xml :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsd:complexType name="monType">
      <xsd:sequence>
        <xsd:element name="Command"  type="xsd:string" />
        <xsd:element name="Response" type="xsd:string" />
      </xsd:sequence>
    </xsd:complexType>


    Classe PHP associée
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class monType
    	{
    	public 	$Commande;		
    	public	$Response;
    	}


    Création du webservice:
    Code :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
    	// First step : disable the cache
    	ini_set("soap.wsdl_cache_enabled", "0");
     
    	// Define a mapping between WSDL's type and PHP's classes
    	$classmap = array('monType'     => 'monType');
     
    	// Link the SoapClient with our WSDL and our classmap
    	$clientSOAP = new SoapClient
    		(
    		dirname(__FILE__) . "/../WSDL/myServer.wsdl",
    		array
    			(
    			"trace"      => 1,
    			"exceptions" => 0,
    			'classmap' => $classmap
    			)
    		);

  5. #5
    Membre averti
    Bon j'avais testé juste après ton message, mais ca ne marchait point. Donc une nouvelle fois j'ai reporté, avec du recul ca passe toujours mieux, sauf que desfois on a pas le temps pour cela, et c'est mon cas maintenant ^^

    Donc j'ai repris du début, j'ai fait un truc tout simple :
    Je prends en paramètre 2 nombres (a et b) et je renvoie leur somme. Difficile de trouver moins compliqué.

    J'ai un soucis, je ne reçois que le nombre a, le nombre b ne passe pas...
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function Add ($a, $b) 
    {
    	$bla = $a + $b;
    	return $bla;
    }

    Même quand je fais ceci, cela me renvoie rien du tout :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function Add ($a, $b) 
    {
    	return $b;
    }


    Donc j'ai testé pas mal de choses, mais rien de fonctionne... Je vous passe mon code, si vous avez le temps pour y jeter un coup d'oeil, je vais continuer à bosser dessus de mon côté.

    Déclaration du serveur :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $server = new SoapServer('Webservice.wsdl', array('soap_version' => SOAP_1_1,'encoding' => 'utf-8'));
    $server->setClass('myWebService');
     
    class myWebService 
    {
    	function Add ($a, $b) 
    	{
    		$bla = $a + $b;
    		return $bla;
    	}
    }


    Création du Client, et appel de la fonction Add :
    Code :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
    class AddRequest {
    	public $number_a;
    	public $number_b;
    }
    class AddResponse {
    	public $return_add;
    }
     
    ini_set("soap.wsdl_cache_enabled", "0");
    $classmap = array ('AddRequest' => 'AddRequest', 'AddResponse' => 'AddResponse');
    $client = new SoapClient('Webservice.wsdl', array ('trace' => 1, 'exceptions' => 0, 'classmap' => $classmap));
     
    $res = $client->Add($nb_a,$nb_b);
     
    if (is_soap_fault($res))
    	echo trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
    else
    	echo "Le total fait : $res";


    Et le pavé pour la fin... le WSDL ! Je le met en entier désolé... mais il me faut des yeux extérieurs pour capter la moindre petite erreur "à la con" (si je puis me permettre ^^) :
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    <?xml version="1.0" encoding="utf-8"?>
     
    <wsdl:definitions name="WebService"
    targetNameSpace="urn:WebService"
    xmlns:tns="urn:WebService"
    xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="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="http://schemas.xmlsoap.org/wsdl/http/">
     
     
    	<wsdl:types>
    		<xsd:schema elementFormDefault="qualified" targetNamespace="urn:WebService">
     
    			<xsd:complexType name="AddRequest">
    			  <xsd:sequence>
    				<xsd:element minOccurs="1" maxOccurs="1" name="number_a" type="xsd:int" />
    				<xsd:element minOccurs="1" maxOccurs="1" name="number_b" type="xsd:int" />
    			  </xsd:sequence>
    			</xsd:complexType>
     
    			<xsd:complexType name="AddResponse">
    			  <xsd:sequence>
    				<xsd:element minOccurs="1" maxOccurs="1" name="return_add" type="xsd:int" />
    			  </xsd:sequence>
    			</xsd:complexType>
     
    		</xsd:schema>
    	</wsdl:types>
     
     
    	<wsdl:message name="AddSoapIn">
    		<wsdl:part name="parameters" element="tns:AddRequest" />
    	</wsdl:message>
    	<wsdl:message name="AddSoapOut">
    		<wsdl:part name="parameters" elemebt="tns:AddResponse" />
    	</wsdl:message>
     
     
    	<wsdl:portType name="WebServPorts">		
    		<wsdl:operation name="Add">
    			<wsdl:input  message="tns:AddSoapIn"/>
    			<wsdl:output message="tns:AddSoapOut"/>
    		</wsdl:operation>
    	</wsdl:portType>
     
     
    	<wsdl:binding name="WebServBinding" type="tns:WebServPorts">
    		<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
     
    		<wsdl:operation name="Add">
    			<soap:operation soapAction="AddAction"/>
    			<wsdl:input>
    				<soap:body use="literal" />
    			</wsdl:input>
    			<wsdl:output>
    				<soap:body use="literal" />
    			</wsdl:output>
    		</wsdl:operation>
     
    	</wsdl:binding>
     
     
    	<wsdl:service name="WebServService">
            <wsdl:port name="WebServPorts" binding="typens:WebServBinding">
    			<soap:address location="http://localhost/v0.420.ComplexTypeTests/webservice.php"/>
    		</wsdl:port>
    	</wsdl:service>
     
     
    </wsdl:definitions>

  6. #6
    Membre averti
    Bon je suis pratiquement sûr que le problème vient de mon fichier WSDL.
    J'ai essayé plusieurs trucs, placés mes definitions de complexType dans des <element name="..">, j'ai testé de changer le mode de transport des données, en document/literal, rpc/encoded...
    Puisque a priori, placer plus de <part> dans un <element> n'est pas conforme à la norme WS-I, donc... ma méthode de base vue dans au début du topic, n'est pas conforme...

    Je nage et je me noie, j'ai vraiment besoin d'aide

  7. #7
    Membre expert
    J'ai regardé ton wsdl pour le comparer au mien, j'ai deux "différences" je ne sais pas du tout si c'est lié mais a tout hasard je te donne mon WSDL pour que tu puisses comparer (entre autres j'ai défini un namespace xsd1 et je mets plus d'infos que toi dans le binding
    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
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    <?xml version="1.0"?>
    <!-- part 1 : Definitions -->
    <definitions 	name="myServer"
    				targetNamespace="myServer"
    				xmlns="http://schemas.xmlsoap.org/wsdl/"
                    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    				xmlns:tns="myServer"
    				xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema"
    				xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd1="myServer-xsd"
                    xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance">
     
    <!-- part 2 : Types-->
    <types>
       <xsd:schema 	targetNamespace="myServer-xsd"
               		xmlns="http://www.w3.org/2001/XMLSchema"
               		xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
     
    	  <!-- Input connection parameters -->
     
          <xsd:complexType name="SqCommandsArray">
             <xsd:complexContent>
                <xsd:restriction base="SOAP-ENC:Array">
                   <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]" />
                </xsd:restriction>
             </xsd:complexContent>
          </xsd:complexType>
     
          <xsd:complexType name="SqCommands">
             <xsd:sequence>
                <xsd:element name="NumberOfCommands" 	type="xsd:int" maxOccurs="1" minOccurs="1"/>
                <xsd:element name="ListOfCommands"		type="xsd1:SqCommandsArray" />
             </xsd:sequence>
          </xsd:complexType>
     
          <xsd:complexType name="doCommandRequest">
             <xsd:sequence>
                <xsd:element name="SqAction" 	type="xsd:int" 			maxOccurs="1" minOccurs="1"/>
                <xsd:element name="SqId" 		type="xsd:int" 			maxOccurs="1" minOccurs="0"/>
                <xsd:element name="SqCommands" 	type="xsd1:SqCommands" 	maxOccurs="1" minOccurs="0"/>
             </xsd:sequence>
          </xsd:complexType>
     
     
    	  <!-- Output connection parameters -->
     
          <xsd:complexType name="SpCommandAndResponse">
             <xsd:sequence>
                <xsd:element name="Command"  type="xsd:string" />
                <xsd:element name="Response" type="xsd:string" />
             </xsd:sequence>
          </xsd:complexType>
     
          <xsd:complexType name="ListOfCommandsAndResponsesArray">
             <xsd:complexContent>
                <xsd:restriction base="SOAP-ENC:Array">
                   <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd1:SpCommandAndResponse[]" />
                </xsd:restriction>
             </xsd:complexContent>
          </xsd:complexType>
     
          <xsd:complexType name="SpCommandsAndResponses">
             <xsd:sequence>
                <xsd:element name="NumberOfResponses" 		type="xsd:int" maxOccurs="1" minOccurs="1"/>
                <xsd:element name="ListOfCommandsAndResponses"	type="ListOfCommandsAndResponsesArray" />
             </xsd:sequence>
          </xsd:complexType>
     
     
          <xsd:complexType name="doCommandResponse">
             <xsd:sequence>
                <xsd:element name="SpAction" 				type="xsd:int" 					maxOccurs="1" minOccurs="1"/>
                <xsd:element name="SpId" 					type="xsd:int" 					maxOccurs="1" minOccurs="0"/>
                <xsd:element name="SpCommandsAndResponses"	type="SpCommandsAndResponses" 	maxOccurs="1" minOccurs="0"/>
                <xsd:element name="SpStatus" 				type="xsd:int" 					maxOccurs="1" minOccurs="1"/>
             </xsd:sequence>
          </xsd:complexType>
        </xsd:schema>
     </types>
     
    <!-- part 3 : Message -->
    <message name="doCommandRequest">
       <part name="myRequest" type="xsd1:doCommandRequest" />
    </message>
     
    <message name="doCommandResponse">
       <part name="myResponse" type="xsd1:doCommandResponse" />
    </message>
     
    <!-- part 4 : Port Type -->
    <portType name="myServerPort">
       <!-- partie 5 : Operation -->
       <operation name="doCommand">
          <input  message="tns:doCommandRequest"  name="doCommandInput"/>
          <output message="tns:doCommandResponse" name="doCommandOutput"/>
       </operation>
    </portType>
     
    <!-- part 6 : Binding -->
    <binding name="myServerBinding"
             type="tns:myServerPort">
       <soap:binding style="rpc"
                     transport="http://schemas.xmlsoap.org/soap/http"/>
       <operation name="doCommand">
          <soap:operation soapAction="myServer"/>
          <input name="doCommandInput">
             <soap:body use="encoded"
                        namespace="myServer"
    		    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </input>
          <output name="doCommandOutput">
             <soap:body use="encoded"
    		    namespace="myServer"
    		    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
          </output>
       </operation>
    </binding>
     
    <!-- part 7 : Service -->
    <service name="myServer">
       <!-- part 8 : Port -->
       <port name="myServerPort"
             binding="tns:myServerBinding">
          <soap:address location="http://127.0.0.1/myServer/doCommandProcessing.php"/>
       </port>
    </service>
    </definitions>

  8. #8
    Membre averti
    Bon déjà j'ai trouvé une faute de frappe dans le WSDL (genre de truc qui m'arrive souvent et qui me donne envie de me pendre), je l'ai corrigé, j'avais de nouveaux messages d'erreurs.
    J'ai ensuite modifié mon WSDL pour faire un peu à ta "façon", même si peu de choses ne changent ^^
    Pour le xsd1, je n'en vois pas trop l'utilité dans mon cas, mais je saurais maintenant qu'il faudra en définir un pour utiliser des complexType dans d'autres complexType.

    Donc résultat maintenant, j'ai toujours le même problème... Je ne reçois que le nombre a.

    J'ai une question,
    Est-ce que ceci :
    Code xml :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    <xsd:complexType name="AddRequest">
    ...
    </xsd:complexType>
    est équivalent à :
    Code xml :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsd:element name="AddRequest">
    <xsd:complexType>
    ...
    </xsd:complexType>
    </xsd:element>
    ?
    Je suis sûr que ca doit dépendre des cas évidemment...

    Il y a des parties encore très floues dans mes connaissances du WSDL...

    Je sens de plus en plus que c'est une erreur bien à la con, et ca m'embête de perdre mon temps et de faire perdre le tien

  9. #9
    Membre expert
    je ne sais pas du tout si c'est équivalent, personnellement j'ai réussi a avoir un WSDL fonctionnel, et je n'y ai pas retouché depuis un an, je l'utilise tel quel...

  10. #10
    Membre averti
    Quelle est la différence entre ces 2 appels ?
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    $client -> __soapCall('Add', array ($nb_a, $nb_b));
    $client->Add($nb_a,$nb_b);

    Ou encore une fois, c'est la même chose...

    Sinon je pense maintenant que c'est une erreur dans mon code php... Pourtant ya pas plus simple. Je vous mets mon code, si un truc vous choque...

    Coté serveur :
    Code :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
    <?php
     
     
    // Désactivation du cache WSDL
    ini_set("soap.wsdl_cache_enabled", "0");
    //Force la lecture de donnés et les met manuellement dans la variable
    $HTTP_RAW_POST_DATA = file_get_contents('php://input');
    $server = new SoapServer('Webservice.wsdl', array('soap_version' => SOAP_1_1, 'encoding' => 'utf-8')); 
    $server->setClass('myWebService');
     
    // Classe qui va gérer les requetes SOAP
    class myWebService 
    {
    	function Add ($a, $b) 
    	{
    		$bla = $a + $b;
    		return $bla;
    	}
    }
     
    // La méthode POST a été utilisée pour appeller cette page. On suppose donc qu'une requète a été envoyée, on la gère
    if ($_SERVER['REQUEST_METHOD'] == 'POST')
    {
    	$server->handle();
    }
    // sinon, on affiche une liste des méthodes que peut gérer ce serveur
    else
    {
    	echo '<strong>This SOAP server can handle following functions : </strong>';    
        echo '<ul>';
        foreach($server -> getFunctions() as $func) {        
            echo '<li>' , $func , '</li>';
        }
        echo '</ul>';
    }
    ?>


    Coté client :
    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
    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
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
        <head>
            <title>Tests ComplexType</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        </head>
        <body>
    	<a href="http://localhost/v0.420.ComplexTypeTests/">Retour</a>
    	</br>
    	<form method="post" action="Client.php">
    		A :	<input type="text" name="nb_a" size="10"> </br>
    		B :	<input type="text" name="nb_b" size="10"> </br>
    		<input type="submit" value="OK" />
    	</form>
     
    <?php
    	class AddRequest {
    		public $number_a;
    		public $number_b;
    	}
     
    	class AddResponse {
    		public $return_add;
    	}
     
    	ini_set("soap.wsdl_cache_enabled", "0");
    	$classmap = array ('AddRequest' => 'AddRequest', 'AddResponse' => 'AddResponse');
    	$client = new SoapClient('Webservice.wsdl', array ('trace' => 1, 'exceptions' => 0, 'classmap' => $classmap));
     
    	// Verification si les 2 variables existent
    	if ( 	isset($_POST['nb_a']) AND ($_POST['nb_a']!=NULL) AND
    		isset($_POST['nb_b']) AND ($_POST['nb_b']!=NULL))
    	{
    		$nb_a = $_POST['nb_a'];
    		$nb_b = $_POST['nb_b'];
    		echo "</br> A = $nb_a / B = $nb_b </br>";
    		$res = $client -> __soapCall('Add', array ($nb_a, $nb_b));
    		//$res = $client->Add($nb_a,$nb_b);
     
    		if (is_soap_fault($res))
    			 echo trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
    		else
    			echo "Le total fait : $res";
    	}
    	else
    		echo "Aucune valeur rentree </br>";
    ?>
     
    	</body>
    </html>

  11. #11
    Membre averti
    Bon... Je suis vraimend désespéré la

    J'ai simplifié au maximum mon code, j'ai fait en sorte que mon fichier WSDL ressemble beaucoup au l'exemple de koopajah. Et pourtant toujours ce 2e paramètre qui veut pas passer... Je dois zapper un truc d'important mais je ne sais vraiment pas quoi.

    Voici mon code simplifié :
    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
    21
    <?php
    class doAddRequest 
    {
    	public $nb_a;
    	public $nb_b;
    }
    class doAddResponse 
    {
    	public $return_add;
    }
    ini_set("soap.wsdl_cache_enabled", "0");
    $classmap = array ('doAddRequest' => 'doAddRequest', 'doAddResponse' => 'doAddResponse');
    $client = new SoapClient('Webservice.wsdl', array ('trace' => 1, 'exceptions' => 0,'classmap' => $classmap));
     
    $nb_a = 11;
    $nb_b = 22;
    echo "</br> A = $nb_a / B = $nb_b </br>";
    //$res = $client -> __soapCall('doAdd', array ($nb_a, $nb_b));
    $res = $client->doAdd($nb_a,$nb_b);
    echo "Le total fait : $res";
    ?>

    Webservice.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
    <?php
    ini_set("soap.wsdl_cache_enabled", "0");
    $HTTP_RAW_POST_DATA = file_get_contents('php://input');
     
    $server = new SoapServer('Webservice.wsdl');
    $server->addFunction('doAdd');
    $server->handle();
     
    function doAdd ($nb_a, $nb_b) 
    	{
    		$return_add = $nb_a + $nb_b;
    		return $return_add;
    	}
    ?>

    Webservice.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
    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
    <?xml version="1.0"?>
     
    <definitions 	name="WebService"
    				targetNameSpace="WebService"
    				xmlns="http://schemas.xmlsoap.org/wsdl/"
    				xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    				xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    				xmlns:tns="WebService"
    				xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema" 
    				xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd1="WebService-xsd"
    				xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance">
     
    	<types>
    		<xsd:schema targetNamespace="WebService-xsd"
    					xmlns="http://www.w3.org/2001/XMLSchema"
    					xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
     
    			<xsd:complexType name="doAddRequest">
    			  <xsd:sequence>
    				<xsd:element name="nb_a" type="xsd:int" minOccurs="1" maxOccurs="1" />
    				<xsd:element name="nb_b" type="xsd:int" minOccurs="1" maxOccurs="1" />
    			  </xsd:sequence>
    			</xsd:complexType>
     
    			<xsd:complexType name="doAddResponse">
    			  <xsd:sequence>
    				<xsd:element name="return_add" type="xsd:int" minOccurs="1" maxOccurs="1" />
    			  </xsd:sequence>
    			</xsd:complexType>
     
    		</xsd:schema>
    	</types>
     
     
    	<message name="doAddRequest">
    		<part name="myRequest"  element="xsd1:doAddRequest" />
    	</message>
    	<message name="doAddResponse">
    		<part name="myResponse" element="xsd1:doAddResponse" />
    	</message>
     
     
    	<portType name="WebServPorts">		
    		<operation name="doAdd">
    			<input  message="tns:doAddRequest"  name="doAddInput"  />
    			<output message="tns:doAddResponse" name="doAddOutput" />
    		</operation>
    	</portType>
     
     
    	<binding name="WebServBinding" type="tns:WebServPorts">
    		<soap:binding 	style="rpc"
    						transport="http://schemas.xmlsoap.org/soap/http" />
    		<operation name="doAdd">
    			<soap:operation soapAction="doAddAction"/>
    			<input name="doAddInput">
    				<soap:body 	use="encoded"
    							namespace="WebService"
    							encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    			</input>
    			<output name="doAddOutput">
    				<soap:body  use="encoded"
    							namespace="WebService"
    							encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    			</output>
    		</operation>
    	</binding>
     
    	<service name="WebServService">
            <port name="WebServPorts" binding="tns:WebServBinding">
    			<soap:address location="http://localhost/v0.420.ComplexTypeTests/Webservice.php"/>
    		</port>
    	</service>
     
    </definitions>


    *va mourir au loin*

  12. #12
    Membre averti
    Bon bon... Quand je fais ceci :
    Code xml :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <xsd:complexType name="doAddRequest">
    	<xsd:sequence>
    		<xsd:element name="nb_a" type="xsd:int" minOccurs="1" maxOccurs="1" />
    		<xsd:element name="nb_b" type="xsd:int" minOccurs="1" maxOccurs="1" />
    	</xsd:sequence>
    </xsd:complexType>
     
    <xsd:complexType name="doAddResponse">
    	<xsd:all>
    		<xsd:element name="return_add" type="xsd:int" minOccurs="1" maxOccurs="1" />
    	</xsd:all>
    </xsd:complexType>


    Mes messages SOAP sont :
    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
    Request: 
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope 
    		xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    		xmlns:ns1="WebService" 
    		xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema"
    		xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance" 
    		xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    		SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">	
    		<SOAP-ENV:Body>
    			<ns1:doAdd>
    				<myRequest xsi:type="xsd:int">11</myRequest>
    				<param1 xsi:type="xsd:int">22</param1>
    			</ns1:doAdd>
    		</SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
     
    Response: 
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope 
    	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    	xmlns:ns1="WebService"
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema" 
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    	SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    	<SOAP-ENV:Body>
    		<ns1:doAddResponse>
    			<myResponse xsi:type="xsd:int">11</myResponse>
    		</ns1:doAddResponse>
    	</SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

    Donc déjà gros soucis dans la requête !
    Pourquoi myRequest possède un type simple, alors que c'est censé être un complexType regroupant 2 paramètres. Et pourquoi le param1 s'appelle ainsi, et non pas nb_a ou nb_b...
    Donc c'est bien ici le soucis, dans le fichier WSDL finalement, enfin je crois...


    Un test, quand je fais ceci :
    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
      <xsd:element name="doAddRequest">
    	<xsd:complexType>
    		<xsd:sequence>
    			<xsd:element name="nb_a" type="xsd:int" minOccurs="1" maxOccurs="1" />
    			<xsd:element name="nb_b" type="xsd:int" minOccurs="1" maxOccurs="1" />
    		</xsd:sequence>
    	</xsd:complexType>
    </xsd:element>
     
    <xsd:element name="doAddResponse">
    	<xsd:complexType>
    		<xsd:sequence>
    			<xsd:element name="return_add" type="xsd:int" minOccurs="1" maxOccurs="1" />
    		</xsd:sequence>
    	</xsd:complexType>
    </xsd:element>

    Qui apparemment ne change pas grand chose, j'obtiens ceci :
    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
    Request: 
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope 
    	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    	xmlns:ns1="WebService"
    	xmlns:ns2="WebService-xsd"
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema" 
    	xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    	SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    	<SOAP-ENV:Body>
    		<ns1:doAdd>
    			<myRequest xsi:type="ns2:doAddRequest"/>
    			<param1 xsi:type="xsd:int">22</param1>
    		</ns1:doAdd>
    	</SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
     
    Response: 
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope 
    	xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    	xmlns:ns1="WebService" 
    	xmlns:ns2="WebService-xsd" 
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />si="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd="http://www.w3.org/2001/XMLSchema" 
    	xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    	SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    	<SOAP-ENV:Body>
    		<ns1:doAddResponse>
    			<myResponse xsi:type="ns2:doAddResponse"/>
    		</ns1:doAddResponse>
    	</SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

    Bizarre bizarre...

    Pour le 2e cas, j'ai refait un test en n'utilisant pas mon :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sd1="WebService-xsd"

    Et ca me donne les mêmes messages SOAP du premier cas.

  13. #13
    Membre expert
    Franchement je suis désolé mais je n'y arrive pas là.
    J'ai retourné ton code dans tous les sens, je me suis arraché les cheveux a l'instant mais ca ne marche pas.

    Bon entre temps j'ai eu une illumination ! Tu utilises des classes comme moi et je me rends compte que je ne t'ai pas monté comment je l'utilise ce webservice...
    En fait, il faut pas passer 2 entiers en paramètre de ta fonction, il faut créer une instance de ta classe doAddRequest, et lui affecter les valeurs voulues et ensuite passer cette instance en paramètre

    De la meme manière, coté serveur, il faut définir les memes classes, tu prends en paramète UNE instance de la classe doAddRequest et tu retournes une instance de doAddResponse.

    J'ai tenté de le faire fonctionner mais je fais planter wamp tout entier en bricolant la. Donc je te donne l'info au cas où tu y arrives mieux que moi

    EDIT héhé je viens de voir que tu t'en étais apercu, que les paramètres n'étaient pas bons !

  14. #14
    Membre averti
    Rah ca y est ca marche ! Par contre j'ai fait d'une autre façon
    Avec ce lien :
    http://www.wso2.org/library/1060

    J'ai bien fait comme ils indiquent et cela fonctionne. Voici mes bouts de code php :
    Code php :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Côté client :
    $client = new SoapClient ('Webservice.wsdl', array ('trace'=>1));
    $result =  $client->__soapCall('doAdd', array(array('nb_a' => $nb_a, 'nb_b' => $nb_b)));
    printf("Result = %s\n", $result->return_add);
     
    // La fonction doAdd qui change :
    function doAdd ($param) 
    {
    	$nb_c = $param->nb_a + $param->nb_b;
    	$result = array ('return_add' => $nb_c);
    	return $result;
    }

    Et j'ai modifié mon WSDL, en suivant l'exemple dans le lien, j'avais surtout un problème de namespace à mon avis.

    J'ai vu ton message pendant que je faisais ca, donc j'ai pas essayé ta méthode.
    Et dans ce que je viens de faire je comprends même pas comment ca marche, ca parait trop simple... je pensais que pour des complexType il fallait les mapper sur une classe... mais la j'en ai pas besoin...

    Avancer à tatons dans la noire obscurité nocturne de la nuit...
    Je vais refaire quelques tests après miam miam pour comprendre un peu mieux, enfin essayer...

    Merci de ton implication en tout cas, c'est très gentil
    Pourtant c'est un sujet bien -biiip-...



    Edit : En fait si je comprends bien, il faut mapper le complexType, quand tu ne l'encadres pas par un <element> dans le WSDL. La question que je posais plus haut déjà. Pour chaque méthode, il faut donc un traitement différent dans le code php, ce qui est plutot logique.
    Donc après quelle méthode utiliser... Laquelle est plus conforme ? Aucune idée, j'ai rien lu sur çà, pourtant je m'en suis tappé de la doc !

  15. #15
    Membre expert
    j'étais arrivé a un truc quasi fonctionnel avant d'aller manger mais je ne persiste pas vu que tu as trouvé une solution !
    Perso j'utilise des classes parce que j'ai un empilement de types complexes, avec des tableaux de type complexe etc donc ca devenait trop salle de gérer comme ca !

    Sinon, l'erreur qui faisait completement planter mon WAMP c'est que tu as mis un S majuscule dans targetNameSpace tu le sauras pour plus tard!

    Bon courage en tout cas avec les webservices, tu m'as fait réviser un peu !

  16. #16
    Membre averti
    Citation Envoyé par koopajah Voir le message
    Sinon, l'erreur qui faisait completement planter mon WAMP c'est que tu as mis un S majuscule dans targetNameSpace
    Argh désolé
    Merci pour me l'avoir indiqué je ferais gaffe. C'est fourbe quand même tout ca...

    En tout cas merci pour ton aide, je mets le tag résolu, plus par vengeance (gnark), car il faut que j'applique ca sur mon WebService fonctionnel et complet.

    Si pas de nouvelles, bonne nouvelles

  17. #17
    Nouveau Candidat au Club
    Consommer un serveur soap renvoyant un complex type
    Bonjour!

    Je m'excuse de poster cette question à la suite d'une discution, mais est ce que quelqu'un pourrait m'aider à savoir comment faire pour créer une nouvelle discussion?

    Je travaille sur un web service Soap, développé en Java. Cet Web service a déjà été déployé et fonctionne très bien.
    Moi, j'aimerai créé un client php pour appeler une méthode précise de mon WS.
    La méthode que j'appel prend un "string" en entrée et retourne un objet (complextype).
    J'ai regardé comment créé une classmap pour établir une correspondance entre les classes de mon fichier wsdl et celles du client php (que j'ai pas encore créées d'ailleurs). Mais pour l'instant les info que j'ai eues me disent comment envoyer des données complexes à un serveur soap. Moi, j'aimerais consommer des données complexe.

    J'ai mis qlq fichiers en pièces jointes.
    Un extrait de mon fichier wsdl
    Un extrait de mon client php
    une première réponse que j'ai eue après exécution de mon client.

    Quelqu'un saurait comment faire pour consommer un complextype renvoyé par un serveur soap? Un tuto ou toute idée, je suis preneur.
    Je vous remercie d'avance

###raw>template_hook.ano_emploi###