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 :

[Web Service] classmap - Pas de lien avec le type WSDL


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut [Web Service] classmap - Pas de lien avec le type WSDL
    Bonjour,

    Je voudrais pouvoir mapper un type WSDL avec un objet PHP au niveau de mon client, et cela ne fonctionne pas : j'obtiens toujours un objet de type stdclass.

    Avez vous déjà rencontré ce problème ?

    Voici mon code coté serveur :

    - serveur de webservices : testServeur.php

    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
    <?php
    // on inclue la classe contenant l'objet
    include("class.test.php");
     
    // On tente d'instancier la classe soapServer
    // Si cela s'avère impossible, on lève une exception
    try {
    	//ini_set('soap.wsdl_cache_enabled', 0);
        	$server = new SoapServer('test.wsdl',  array('trace' => 1, 'encoding'=>'ISO-8859-1'));
     
        // On définit la classe qui va gérer les requètes SOAP
        $server -> setclass('classtest');
    } catch (Exception $e) {
        echo $e;
    }
     
    // 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['REQUEST_METHOD'] == 'GET' ) {
        $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>';
    }
     
    ?>
    - class de traitement coté serveur : class.test.php

    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
    <?
    class person {
    	public $name;
     
    	function getName() {
    		return $name;	
    	}
     
    }
     
     
    class classtest 
    {
     
     
      function getPerson($nom) {
     
    	$personne = & new person();
    	$personne->name = $nom;
     
    	return $personne;
     
     
      }
     
    }
     
     
    ?>
    - le wsdl : test.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
    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost/myns/" xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://localhost/myns/">
     
    <types>
    	<xsd:schema>
    		<complexType name="person">
    				<all>
    					<element name="name" type="xsd:string"/>
    				</all>
    		</complexType>
    	</xsd:schema>
    </types>
     
     
    <message name="getPersonInput">
    	<part name="chaine" type="xsd:string"/>
    </message>
     
    <message name="getPersonOutput">
    	<part name="retour" type="tns:person"/>
    </message>
     
     
    <portType name="TestPortType">
    	<operation name="getPerson">
    		<input message="tns:getPersonInput"/>
    		<output message="tns:getPersonOutput"/>
    	</operation>
    </portType>
     
    <binding name="TestBinding" type="tns:TestPortType">
    	<soap-env:binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    	<operation xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/" name="getPerson">
    		<input xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/">
    			<soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    		</input>
    	</operation>
    </binding>
     
    <service name="TestService">
    	<port xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/" name="TestPort" binding="tns:TestBinding">
    		<soap-env:address xmlns="http://schemas.xmlsoap.org/wsdl/soap/" location="http://localhost/ws/test/testServeur.php"/>
    	</port>
    </service>
     
    </definitions>
    Et voici mon client : testClient.php

    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
    <?
    class person {
    	public $name;
     
    	function getName() {
    		return $name;	
    	}
     
    }
     
     
     
    $_adr_portail = "http://localhost";
    $_chemin_ws = "/ws/test/";
     
    $classmap = array("person" => "person");
    ini_set('soap.wsdl_cache_enabled', 0);
     
    $_options = array(
    		"classmap" => $classmap,
    		"trace" => 1,
    		"namespace" =>  $_adr_portail."/myns/"
    		);
    $ficWSDL = $_adr_portail.$_chemin_ws."testServeur.php?WSDL";
    $_clientSOAP =  new SoapClient($ficWSDL, $_options);
     
    $retour = $_clientSOAP->getPerson("toto");
     
    print "<pre>";
    print_r($retour);
    print "</pre>";
     
    echo $retour->getName();
     
    ?>
    Et voici le resultat sous IE :

    stdClass Object
    (
    [name] => toto
    )
    Fatal error: Call to undefined method stdClass::getName() in D:\wamp\www\ws\test\testClient.php on line 33



    Merci d'avance pour l'aide que vous pouvez m'apporter !

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Points : 64
    Points
    64
    Par défaut
    Bonjour,

    Ca ne répond pas directement à la question, mais ça peut être lié.

    Vu le code de testServeur.php, je ne vois comment le client peut obtenir le wsdl en requérant <path>/testServeur.php?WSDL.

    Dans ton wsdl, dans le binding, tu ne définis rien sur le output, tu n'as défini que ton input.

  3. #3
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci de ta réponse, mais malgré mon oubli, ça ne change rien au fait que le classmap ne me type pas ma réponse en objet "person"...

    Voici mon nouveau 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
    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost/myns/" xmlns:soap-env="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://localhost/myns/">
     
    <types>
    	<xsd:schema>
    		<complexType name="person">
    				<all>
    					<element name="name" type="xsd:string"/>
    				</all>
    		</complexType>
    	</xsd:schema>
    </types>
     
     
    <message name="getPersonInput">
    	<part name="chaine" type="xsd:string"/>
    </message>
     
    <message name="getPersonOutput">
    	<part name="retour" type="tns:person"/>
    </message>
     
     
    <portType name="TestPortType">
    	<operation name="getPerson">
    		<input message="tns:getPersonInput"/>
    		<output message="tns:getPersonOutput"/>
    	</operation>
    </portType>
     
    <binding name="TestBinding" type="tns:TestPortType">
    	<soap-env:binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    	<operation xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/" name="getPerson">
    		<input xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/">
    			<soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    		</input>
    		<output xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/">
    			<soap-env:body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    		</output>
    	</operation>
    </binding>
     
    <service name="TestService">
    	<port xmlns:default="http://schemas.xmlsoap.org/wsdl/soap/" name="TestPort" binding="tns:TestBinding">
    		<soap-env:address xmlns="http://schemas.xmlsoap.org/wsdl/soap/" location="http://localhost/ws/test/testServeur.php"/>
    	</port>
    </service>
     
    </definitions>

    Je suis sûre que c'est tout bête mais là j'avoue que je sèche complétement...

    Si tu vois autre chose, n'hésites pas !

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Points : 64
    Points
    64
    Par défaut
    Alors, en relisant de plus près, tes codes sont plein de surprises :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class person {
    	public $name;
     
    	function getName() {
    		return $name; // Ceci sera mieux : return $this->name;
                    // n'oublie pas de changer côté client ET serveur
    	}
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      function getPerson($nom) {
     
    	$personne = & new person(); // je ne vois pas où tu veux en venir avec le &
    	$personne->name = $nom;
     
    	return $personne;
     
     
      }
    J'ai exécuté ton code chez moi, bien entendu, <path>/testServeur.php?wsdl ne renvoie pas de wsdl donc ça plante. Je serais curieux de savoir comment tu arrives sans encombre jusqu'à la récupération de la stdClass...

    Sinon, j'ai trouvé pourquoi ton classmap n'agit pas.
    Tu ne déclares pas ton type person sur le namespace que tu as préfixé tns, donc lorsque tu indiques tns:person comme type, ça ne se résoud pas.

    il faut donc préciser le targetNamespace de ton schema :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <types>
            <xsd:schema targetNamespace="http://localhost/myns/">
                <xsd:complexType name="person">
                    <xsd:all>
                        <xsd:element name="name" type="xsd:string"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:schema>
        </types>

  5. #5
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Un énorme merci à toi pandrogynik car ça marche !!!! Wahouuuu !

    L'ajout du targetNamespace dans le schéma fait toute la différence !!!

    Je vais tout de même te répondre quant aux différentes "surprises" dont tu me parles car il y a des explications !

    class person {
    public $name;

    function getName() {
    return $name; // Ceci sera mieux : return $this->name;
    // n'oublie pas de changer côté client ET serveur
    }

    }
    Effectivement, je m'étais trompé lorsque j'ai posté mais je m'en suis vite rendu compte lors de mes tests. Erreur d'étourderie.

    function getPerson($nom) {

    $personne = & new person(); // je ne vois pas où tu veux en venir avec le &
    $personne->name = $nom;

    return $personne;


    }
    Le & permet de récupérer une référence et non la variable en tant que telle mais ce n'est pas très important à vrai dire, c'est une habitude prise au niveau du taf.

    J'ai exécuté ton code chez moi, bien entendu, <path>/testServeur.php?wsdl ne renvoie pas de wsdl donc ça plante. Je serais curieux de savoir comment tu arrives sans encombre jusqu'à la récupération de la stdClass...
    J'avoue que j'ai toujours utilisé cette façon pour récupérer le endpoint du WS (WSDL). Je suppose que c'est grace à la fonction handle() du serveur SOAP qui quand elle obtient en variable GET "WSDL" affiche le contenu du WSDL. Il faut peut être une configuration particulière pour son bon fonctionnement. J'ai commencé à chercher sur le net, mais je n'ai rien trouvé de particulier sur ce sujet et n'ayant pas beaucoup de temps en ce moment, j'essayerais de voir cela plus tard.

    En tout cas, je te remercie beaucoup d'avoir pris du temps pour résoudre mon problème !

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Points : 64
    Points
    64
    Par défaut
    De rien, c'était un plaisir (j'ai bidouillé pas mal avant de mettre le doigt dessus).

    Je connais le sens du &, mais techniquement il n'a rien à faire là. D'ailleurs sur mon système, j'ai un avertissement comme quoi c'est fortement déprécié.

    Si on fait

    $a est une référence sur $b, ok. C'est déjà difficile dans les méthodologies de conception d'aujourd'hui de justifier le besoin d'y recourir avec des variables de types standard, et c'est le plus souvent une source d'erreur et de side effects surprise a posteriori. Sur une variable objet, encore plus bizarre. Mais alors sur un new !? Là je reste sans voix !

  7. #7
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Effectivement en PHP5 le & n'a plus sa place, mais historiquement l'application était en PHP4, du coup j'ai gardé cette habitude. Mais si cela te gène, faut comme si il n'y avait pas de & !

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Points : 64
    Points
    64
    Par défaut
    A vrai dire, je me doutais que cette pratique était originaire du PHP4, où le modèle "objet" ne l'était pas, puisque les soit-disant instances d'objet passées en paramètres de fonctions étaient des structures copiées par valeur et non pas passées par référence.

    Mais attention, avec un modèle comme celui de PHP5, le maintien de l'utilisation du & peut créer du danger !

    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
    class Object
    {
        public $attribute;
    }
     
    function useless(Object $param)
    {
        $param->attribute = 'value';
        $param = 0;
    }
     
    $objet = new Object;
     
    useless($object);
     
    echo $object->attribute; // affiche 'value'
     
    useless(& $object);
     
    echo $object->attribute; // Notice: Trying to get property of non-object...
    var_dump($object); // $object est égal à (int) 0 !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/10/2011, 09h49
  2. je trouve asp.net web service mais pas asp.net web application
    Par question87 dans le forum Visual Studio
    Réponses: 1
    Dernier message: 22/04/2008, 21h26
  3. [Web Service][SOAP] Compression des données avec NuSOAP ?
    Par lasdou15 dans le forum Bibliothèques et frameworks
    Réponses: 11
    Dernier message: 17/04/2008, 12h14
  4. [Web Service][SOAP] Message d'erreur avec NuSOAP
    Par batama dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 08/04/2008, 11h59
  5. Réponses: 5
    Dernier message: 04/07/2006, 00h11

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