Problème de débutant poo

Petit nouveau ! | 7 Messages

18 août 2010, 16:22

Bonjour,
Je fais mes premiers pas dans le php objet couplé à pdo, avec le pattern singleton.
J'ai fait une classe bdd qui me connecte à la bdd, avec un singleton pour réutiliser la même instance pour chaque objet, et j'ai écrit une classe acteurMapping pour aller chercher des données dans ma bdd, une classe qui hérite de bdd. Mais j'ai un bug et je câle et il y a bien sur quelque chose, une logique de php objet (ou de l'objet tout court) qui m'échappe...
Voici mon code :
bdd.php

Code : Tout sélectionner

<?php class bdd { private static $_instance = null; protected $connexion; public function __construct() { echo 'constructeur bdd<br />'; try { echo 'instanciation pdo<br />'; $this->connexion = new PDO('mysql:host='.SERVEUR.';port=3306;dbname='.BASE, LOGIN, PWD); var_dump($this->connexion); } catch(Exception $e) { echo 'Erreur : '.$e->getMessage().'<br />'; echo 'N° : '.$e->getCode(); die(); } } final public static function getInstance() { if(is_null(self::$_instance)) { self::$_instance = new bdd(); } return self::$_instance; } /* public function connexion() { return $this->_connexion; } */ private function __clone() { } } ?>
acteurMapping.php

Code : Tout sélectionner

<?php class acteurMapping extends bdd { private $_table; private $_index; //private $_db; public function __construct() { echo 'constructeur acteurMapping<br />'; $this->getInstance(); var_dump($this->connexion); $this->_table = "participant"; $this->_index = "idParticipant"; } public function listeActeur() { $resultats=$this->connexion->query('SELECT nomPart, prenomPart FROM '.$this->_table.' ORDER BY nomPart ASC'); $resultats->setFetchMode(PDO::FETCH_OBJ); // on dit qu'on veut que le résultat soit récupérable sous forme d'objet while( $ligne = $resultats->fetch() ) // on récupère la liste des acteurs { echo $ligne->nomPart.' '.$ligne->prenomPart.'<br />'; // on affiche les acteurs } $resultats->closeCursor(); // on ferme le curseur des résultats } } ?>
index.php

Code : Tout sélectionner

<?php include('entete_php.php'); $listeActeur = new acteurMapping(); $listeActeur->listeActeur(); ?>
j'ai le message :

constructeur acteurMapping
constructeur bdd
instanciation pdo
object(PDO)#3 (0) { } NULL
Fatal error: Call to a member function query() on a non-object in C:\Program Files\EasyPHP 3.0\www\pdo\class\acteurMapping.php on line 23
et donc l'attribut connexion qui est nul.

Merci à celle et ceux qui prendront du temps pour m'aider

Justin

Eléphant du PHP | 314 Messages

18 août 2010, 16:31

Au hasard, étant donné que getInstance est static, il ne faudrait pas faire

self::getInstance();
plutôt que
$this->getInstance() ?
Cordialement,
Julien - http://laravel.fr/

Petit nouveau ! | 7 Messages

18 août 2010, 16:38

J'ai tenté, même chose. Avec parent::getInstance() aussi...

A priori, si je lis les echo, ça fait :

. appel du constructeur de acteurMapping
. appel de la fonction getInstance de bdd
. appel du constructeur de bdd
. affectation d'un objet pdo à l'attribut connexion de bdd
. bug : non affectation d'un objet pdo à l'attribut connexion de acteurMapping pourtant hérité

ça doit être une question de logique objet, non ?

Petit nouveau ! | 7 Messages

18 août 2010, 17:29

J'ai modifié mon code et ça marche mais j'aimerai comprendre ce qui ne fonctionnait pas...
Mon nouveau code :

bdd.php

Code : Tout sélectionner

<?php class bdd { private static $_instance = null; public function __construct() { } final public static function getInstance() { if(is_null(self::$_instance)) { self::$_instance = new PDO('mysql:host='.SERVEUR.';port=3306;dbname='.BASE, LOGIN, PWD); } return self::$_instance; } private function __clone() { } final protected static function bdd_instance() { return self::getInstance(); } } ?>
acteurMapping.php

Code : Tout sélectionner

<?php class acteurMapping extends bdd { private $_table; private $_index; public function __construct() { $this->_table = "participant"; $this->_index = "idParticipant"; } public function listeActeur() { $resultats=$this->bdd_instance()->query('SELECT nomPart, prenomPart FROM '.$this->_table.' ORDER BY nomPart ASC'); $resultats->setFetchMode(PDO::FETCH_OBJ); // on dit qu'on veut que le résultat soit récupérable sous forme d'objet while( $ligne = $resultats->fetch() ) // on récupère la liste des acteurs { echo $ligne->nomPart.' '.$ligne->prenomPart.'<br />'; // on affiche les acteurs } $resultats->closeCursor(); // on ferme le curseur des résultats } } ?>
C'est plus light du coup :wink:

devlop78
Invité n'ayant pas de compte PHPfrance

24 sept. 2010, 22:20

J'ai parcouru très vite le sujet (comme d'ab ...)

Le seul truc que j'ai pu voir c'est l'absence d'appel du constructeur parent depuis ton constructeur enfant ... Et l'erreur n'est pas hors sujet ...

Je ne connais pas assez bien actionscript pour te dire ce qu'il en est en général du comportement d'héritage ... toujours utile qu'en php, on appelle ça la surcharge (si je me souviens bien). Bref ... Outre la théorie, si tu as une classe A avec une méthode x, et une classe B héritée de A avec une méthode x, que doit faire php lorsque tu appelles x à partir de B ? Les développeurs de php ont dû faire un choix ... et sans tous les lister, ils ont choisi que si tu appel x depuis B, alors ce sera la méthode x de B qui sera appelée. Si tu veux appeler la méthode x de A (donc ouvrir ta connexion à la bdd), il faudra lui dire ... par un parent::__construct() par exemple. Bref, si c'est l'inverse, je ne sais plus exactement. Le site du zéro donne un bon exemple avec trois classes héritées, et le mot parent:: self:: et static:: ... Pour les autres méthodes et propriétés uniques, le problème ne se pose pas ...

Perso, je n'utilise pas l'héritage pour l'instant, sauf en actionscript, où c'est presque plus qu'obligatoire (hériter de sprite par exemple ...). J'ai une classe pour la base de données, et elle est bien comme elle est ... les autres classes model (données) l'appellent et l'utilisent ... Et pour le coup, en plus d'éviter ce genre de problèmes (ce qui ne me dérange pas), je préfère voir $this->maclassebdd->query() que $this->query(), $maclassebdd étant une instance de la classe maclassebdd, on peut tout aussi écrire maclassebdd::getInstance()->query().

C'est un peu comme créer une classe héritant de Math() pour calculer une racine carrée ... Pour moi bdd et une classe model n'ont rien de parent, ils ont deux rôles différents ... Je préfère réserver l'héritage à une classe que je veux compléter, que je veux surcharger. Mais la programmation a encore beaucoup à m'apprendre ... heureusement, sinon elle serait bien pauvre !
Modifié en dernier par devlop78 le 24 sept. 2010, 23:32, modifié 1 fois.

ViPHP
ViPHP | 5462 Messages

24 sept. 2010, 22:22

Pour moi bdd et une classe model n'ont rien de parent, ils ont deux rôles différents ...
Tout a fait d'accord :wink:

devlop78
Invité n'ayant pas de compte PHPfrance

24 sept. 2010, 23:35

merci :D