Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1152 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  soap et problème de persistence mysql

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

soap et problème de persistence mysql

n°1709413
madeintom
Posté le 28-03-2008 à 17:30:24  profilanswer
 

Bonjour,
 
Je suis en train de mettre en place un webservice et je veux faire un système d'identification.
Voici le code de la page client.

Code :
  1. $client = new SoapClient(null,array('location'=>'http://xxxx.com/adserverPersist.php','uri'=>'http://xxxx.com/'));
  2. $login = 'login';
  3. $pass = 'pass';
  4. $client->connection($login,$pass);
  5. $rep2 = $client->doSomething();


et voici la class appelée par le SoapServer :

Code :
  1. class Foo {
  2. private $db;
  3. private $login;
  4. private $pass;
  5. public function __construct(){}
  6. public connection($login,$pass){
  7.  $this->login = $login;
  8.  $this->pass = $pass;
  9.  $this->connectDb();
  10. }
  11. private function connectDb(){
  12.  $this->db = new MySQL('localhost',$this->login,$this->pass,'database');
  13. }
  14. public function doSomething(){
  15.  if (!$this->db->isConnected()){
  16.   $this->connectDb();
  17.  }
  18.  $sql = 'select * from table';
  19.  $rqt = $this->db->query($sql);
  20. }
  21. public function doSomethingElse(){
  22.  if (!$this->db->isConnected()){
  23.   $this->connectDb();
  24.  }
  25.  $sql = 'select * from table2';
  26.  $rqt = $this->db->query($sql);
  27. }
  28. }


Si j'essaye d'appeler la méthode doSomething(), la connection est perdue et je dois forcer la reconnection
à la base de donnée pour pouvoir faire mes requetes.
 
Quelqu'un pourrait me dire s'il y a une possibilité de mettre une sorte de persistence en place pour garder
la connection à la base de donnée active ? Mais peut-être est-ce impossible et il faudra au début de chaque
appel de méthode via le webservice que je me reconnecte à la BDD ?  
 
Même si vous n'avez pas la réponse complète, une piste m'aiderai déjà pas mal.
 
Merci d'avance pour votre aide.  
 
Thomas.

mood
Publicité
Posté le 28-03-2008 à 17:30:24  profilanswer
 

n°1710417
pot2yaourt
Posté le 31-03-2008 à 15:44:10  profilanswer
 

Salut,
 
J'ai moi aussi le même problème :
 
Le code du client :
 

Code :
  1. <?php
  2. ini_set("soap.wsdl_cache_enabled", "0" );
  3. $client = new SoapClient("http://127.0.0.1/test/captain.wsdl",
  4.    array('soap_version' => SOAP_1_1, 'encoding' => 'ISO-8859-1', 'style' => SOAP_RPC, 'use' => SOAP_ENCODED));
  5. try
  6. {
  7.   $client->createCaptain("Titi", 20);
  8.   //Le code qui pose problème...
  9.   echo "Nom : ".$client->getCaptainName();
  10. }
  11. catch (SoapFault $exception)
  12. {
  13.   echo "Exception: ".$exception;
  14. }
  15. ?>


 
Le serveur avec les classes Captain et Person :
 

Code :
  1. <?php
  2. class Person
  3. {
  4.   private $name = "Default Name";
  5.   private $age = 99;
  6.   /**
  7.    * Constructeur de la classe
  8.    *
  9.    * @param string $name
  10.    * @param string $firstname
  11.    * @param integer $age
  12.    */
  13.   public function __construct($name, $age)
  14.   {
  15.     $this->name = $name;
  16.     $this->age = (int)$age;
  17.   }
  18.   /**
  19.    * Retourne le nom
  20.    *
  21.    * @return string
  22.    */
  23.   public function getName()
  24.   {
  25.     return $this->name;
  26.   }
  27. }
  28. class Captain
  29. {
  30.   private $captn = null;
  31.   /**
  32.    * Crée un nouveau Capitaine
  33.    *
  34.    * @param string $name
  35.    * @param integer $age
  36.    */
  37.   public function createCaptain($name, $age)
  38.   {
  39.     $this->captn = new Person($name, $age);
  40.   }
  41.   /**
  42.    * Retourne le nom du Capitaine
  43.    *
  44.    * @return string
  45.    */
  46.   public function getCaptainName()
  47.   {
  48.     return $this->captn->getName();
  49.   }
  50. }
  51. // disabling WSDL cache
  52. ini_set("soap.wsdl_cache_enabled", "0" );
  53. // create the new object SoapServer
  54. $server = new SoapServer("http://127.0.0.1/test/captain.wsdl",
  55.    array('soap_version' => SOAP_1_1, 'encoding' => 'ISO-8859-1', 'style' => SOAP_RPC, 'use' => SOAP_ENCODED));
  56. // add class
  57. $server->setClass("Captain" );
  58. // ready to receice xml
  59. $server->handle();
  60. ?>


 
Du coup, après avoir instancié la classe Person via la méthode createCaptain, l'objet ainsi créé est inopérant. C'est bizarre...
 
Faudrait-il stocker l'objet créé en Session :??:  
 
Si qq'un a une idée, ça m'intéresse !!
Lionel.
 

n°1710522
skeye
Posté le 31-03-2008 à 17:33:28  profilanswer
 

pot2yaourt a écrit :


Du coup, après avoir instancié la classe Person via la méthode createCaptain, l'objet ainsi créé est inopérant. C'est bizarre...


Non, c'est normal.
Une variable php meurt à la fin du script.

 

Pour avoir ce que tu essaies d'avoir il faut que ta méthode createCaptain retourne le captain créé, et que tu manipules cet objet, plus le soapclient.
Et le problème est identique au-dessus, en effet.


Message édité par skeye le 31-03-2008 à 17:37:35

---------------
Can't buy what I want because it's free -
n°1710629
pot2yaourt
Posté le 31-03-2008 à 20:41:06  profilanswer
 

Salut !
 
Merci pour ta réponse... effectivement, après qqs modifications ça fonctionne, mais la syntaxe est plutôt bizarre, je ne m'attendais pas à ça.
 
La liste des modifs :
 
Dans la classe Captain, j'ai modifié, entre autres, la méthode createCaptain afin qu'elle retourne l'objet Person qui a été créé :
 

Code :
  1. // Disparition de l'attribut $captn et de la méthode getCaptainName() qui ne sert plus à rien !
  2. class Captain
  3. {
  4.   public function createCaptain($name, $age)
  5.   {
  6.       return new Person($name, $age);
  7.   }
  8. }


 
Quant au client, voici comment je l'ai modifié :
 

Code :
  1. try
  2. {
  3.   $object = $client->createCaptain("Titi", 20);
  4.   // Le code modifié !   
  5.   echo "Nom : ".$object->name;
  6. }
  7. catch (SoapFault $exception)
  8. {
  9.   echo "Exception: ".$exception;
  10. }


 
Mais voilà, d'où sort ce ->name ??  En fait, il s'agit de l'attribut de la classe Person !
 

Code :
  1. class Person
  2. {
  3.   // C'est cet attribut qui est utilisé !
  4.   private $name = "Default Name";
  5.   public function __construct($name, $age)
  6.   {
  7.     $this->name = $name;
  8.     $this->age = (int)$age;
  9.   }
  10.   [...]
  11. }


 
Donc, si la classe Person est modifiée ainsi :
 

Code :
  1. class Person
  2. {
  3.   // Nouveau nom de l'attribut
  4.   private $nameXYZ = "Default Name";
  5.   public function __construct($name, $age)
  6.   {
  7.     $this->nameXYZ = $name;
  8.     $this->age = (int)$age;
  9.   }
  10.   [...]
  11. }


 
Le code du client ressemblera alors à ceci :
 

Code :
  1. try
  2. {
  3.   $object = $client->createCaptain("Titi", 20);
  4.   // Plutôt bizarre, non ???
  5.   echo "Nom : ".$object->nameXYZ;
  6. }
  7. catch (SoapFault $exception)
  8. {
  9.   echo "Exception: ".$exception;
  10. }


 
Enfin voilà, c'est peut-être tout à fait normal, à moins que ce soit moi qui m'y suis mal pris ?!, mais je trouvais la façon de coder un peu bizarre.
Si qq'un à un avis sur la question, ça m'intéresse !
 
Lionel.

n°1710633
skeye
Posté le 31-03-2008 à 20:44:39  profilanswer
 

pourquoi ton objet Person() n'aurait pas une méthode name() qui retourne le nom?


---------------
Can't buy what I want because it's free -
n°1710645
pot2yaourt
Posté le 31-03-2008 à 21:06:23  profilanswer
 

Justement, la classe Person dispose bien d'une méthode getName() qui retourne le nom mais ça ne fonctionne pas !
 
J'obtiens le message d'erreur suivant : Fatal error: Call to undefined method stdClass::getName()  
 
Le code du client modifié :

Code :
  1. try
  2. {
  3.   $object = $client->createCaptain("Titi", 20);
  4.   // Appel de la méthode getName() de la classe Person
  5.   echo "Nom : ".$object->getName();
  6. }
  7. catch (SoapFault $exception)
  8. {
  9.   echo "Exception: ".$exception;
  10. }

n°1710649
skeye
Posté le 31-03-2008 à 21:10:31  profilanswer
 

Ok, j'ai jamais joué avec la lib soap de php, mais c'est possible, et même probable après réflexion que ça ne retourne pas les objets avec leurs méthodes...fais un print_r($object) pour voir ce que tu récupères?


---------------
Can't buy what I want because it's free -
n°1710656
pot2yaourt
Posté le 31-03-2008 à 21:29:03  profilanswer
 

Voilà le résultat du print_r($object); :
 
stdClass Object ( [name] => Titi [age] => 20 )
 
ou encore ceci avec un echo var_export($object, true); :
 
stdClass::__set_state(array( 'name' => 'Titi', 'age' => 20, ))
 
C'est en voyant ce résultat que j'ai testé : $object->name et par miracle ça a marché ! Coup de bol !
 
Au final je trouve ça quand même un peu bizarre... en faisant $object->name c'est comme si on avait accès à un attribut privé. Faudra que je fasse quelques essais pour voir comment ça réagit avec un client dotNet, en C# par exemple.

n°1710658
skeye
Posté le 31-03-2008 à 21:30:05  profilanswer
 

pot2yaourt a écrit :

Voilà le résultat du print_r($object); :
 
stdClass Object ( [name] => Titi [age] => 20 )
 
ou encore ceci avec un echo var_export($object, true); :
 
stdClass::__set_state(array( 'name' => 'Titi', 'age' => 20, ))
 
C'est en voyant ce résultat que j'ai testé : $object->name et par miracle ça a marché ! Coup de bol !
 
Au final je trouve ça quand même un peu bizarre... en faisant $object->name c'est comme si on avait accès à un attribut privé. Faudra que je fasse quelques essais pour voir comment ça réagit avec un client dotNet, en C# par exemple.


 
tu n'as pas accès à un attribut privé du tout. Tu as accès au contenu du flux xml que t'as retourné ton webservice...


---------------
Can't buy what I want because it's free -
n°1710676
pot2yaourt
Posté le 31-03-2008 à 21:52:41  profilanswer
 

skeye a écrit :


tu n'as pas accès à un attribut privé du tout. Tu as accès au contenu du flux xml que t'as retourné ton webservice...


 
Oui, c'est exact, ce que je voulais dire c'est que le print_r tout comme le var_export font apparaître le nom d'un attribut privé de la classe. L'attribut étant privé, on n'a pas à savoir comment il s'appelle.

mood
Publicité
Posté le 31-03-2008 à 21:52:41  profilanswer
 

n°1710681
skeye
Posté le 31-03-2008 à 21:54:37  profilanswer
 

pot2yaourt a écrit :


 
Oui, c'est exact, ce que je voulais dire c'est que le print_r tout comme le var_export font apparaître le nom d'un attribut privé de la classe. L'attribut étant privé, on n'a pas à savoir comment il s'appelle.


 
non, c'est là que tu te trompes. TU ne récupères pas un Person, mais un objet standard.


---------------
Can't buy what I want because it's free -
n°1710705
pot2yaourt
Posté le 31-03-2008 à 22:21:38  profilanswer
 

Ah ok, j'avais effectivement pas vu ça comme ça... en fait je souhaitais à tout prix récupérer un objet Person, c'est pour ça !
 
Encore merci pour toutes ces infos !
Lionel.

n°1710708
skeye
Posté le 31-03-2008 à 22:23:33  profilanswer
 

pot2yaourt a écrit :

Ah ok, j'avais effectivement pas vu ça comme ça... en fait je souhaitais à tout prix récupérer un objet Person, c'est pour ça !

 

Encore merci pour toutes ces infos !
Lionel.

 

il y a peut-être moyen, mais en incluant ta classe Person dans le client, et faut voir si ça passe...sinon je pense pas qu'il veuille.


Message édité par skeye le 31-03-2008 à 22:23:40

---------------
Can't buy what I want because it's free -
n°1710897
madeintom
Posté le 01-04-2008 à 11:36:11  profilanswer
 

Merci pour toutes vos réponses même si elles ne répondent pas au problème.
 
Retourner l'objet et faire un print_r(), ne me servira à rien dans mon cas car, je vais bien récupérer les valeurs des variables standards (int, string, etc...). Mais pour une connection à une base de donnée, je suis automatiquement déconnecté.
 

Citation :

il y a peut-être moyen, mais en incluant ta classe Person dans le client, et faut voir si ça passe...sinon je pense pas qu'il veuille.


 
De plus, il ne faut surtout pas faire çà, car le client du webservice n'est pas censé connaître le moteur et donc les objets utilisés sur la partie serveur. Si le client connait la class Person, à quoi sert de faire un webservice ?
 

n°1710903
skeye
Posté le 01-04-2008 à 11:39:59  profilanswer
 

madeintom a écrit :

Merci pour toutes vos réponses même si elles ne répondent pas au problème.

 

Retourner l'objet et faire un print_r(), ne me servira à rien dans mon cas car, je vais bien récupérer les valeurs des variables standards (int, string, etc...). Mais pour une connection à une base de donnée, je suis automatiquement déconnecté.

 

Non, tu n'es pas déconnecté. Tu fais exactement la même erreur que lui, en pensant que deux appels à des fonctions différentes d'un même webservice par le même programme ne sont pas traités individuellement mais en groupe par le serveur.

 

[edit]

 

Je ne vois même pas pour quelle raison farfelue ton client saurait que le serveur doit se connecter à une base de données, d'ailleurs.


Message édité par skeye le 01-04-2008 à 11:42:31

---------------
Can't buy what I want because it's free -
n°1710913
madeintom
Posté le 01-04-2008 à 11:48:54  profilanswer
 

Donc tu veux dire que chaque méthode de l'objet utilisé par le webservice doit se reconnecter à chaque appel du client ? En soit, je peux comprendre.  
 
Mais, donc on en revient à ma question du départ... N'existe-t-il pas une solution pour faire "persister" la connection active à la base de donnée pendant un certain temps ?
 
Suis-je obligé d'avoir le code suivant :
 

Code :
  1. class Foo {
  2. private $db;
  3. private $login;
  4. private $pass;
  5. public function __construct(){}
  6. public connection($login,$pass){
  7. $this->login = $login;
  8. $this->pass = $pass;
  9. }
  10. private function connectDb(){
  11. $this->db = new MySQL('localhost',$this->login,$this->pass,'database');
  12. }
  13. public function doSomething(){
  14.   $this->connectDb();
  15. $sql = 'select * from table';
  16. $rqt = $this->db->query($sql);
  17. }
  18. public function doSomethingElse(){
  19.   $this->connectDb();
  20. $sql = 'select * from table2';
  21. $rqt = $this->db->query($sql);
  22. }
  23. }

n°1710922
skeye
Posté le 01-04-2008 à 11:55:36  profilanswer
 

Oui, tu es grosso modo obligé. Il faut que tu gardes en mémoire chaque fonction publiée par ton webservice sera exécutée par le serveur comme un script autonome...et une ressource de connexion ne peut pas persister entre deux scripts.


---------------
Can't buy what I want because it's free -

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  soap et problème de persistence mysql

 

Sujets relatifs
probléme affichage d'une longue chaine de caractéreProblème de clic sur controle TEdit
Problème pour faire une requête SQL.problème avec session_start()
[SGBD/SQL] Utiliser un index ? Quand ? Comment ?[Mysql] Selection max
[C++] QT + MySQLProblème d'itérateur
auto_increment et Mysql 3.23Trigger / caractère echappement ss MySQL
Plus de sujets relatifs à : soap et problème de persistence mysql


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR