Appel d'un objet PDO

Eléphant du PHP | 226 Messages

07 oct. 2011, 11:25

Bonjour/ bonsoir,

Sans intégrer un modèle MVC pour l'instant, j'essaye de m'en rapprocher en séparant les couches. j'ai donc 3 fichiers:
Un premier fichier, qui sera visible par le navigateur et que je pourrai appeler 'vue'
<?php
require '../controller/controllerProd.php';
// affichage d'une liste de produits
if (!empty ($_GET['production'])) {
    $controlProd->setListe($_GET['production']);
}
?>
...
<div id="content-data">
  <table width="100%" border="0" cellpadding="0" cellspacing="0" id="liste-fiches">
...
Un second fichier, qui pourrait être considéré comme un controller...
require '../core/connect.php';
require '../model/ModelProduction.php';

class ControllerProd {

    var $modelProduction;
    
    function __construct() {
// Initialise l'objet modelProduction
        $this->modelProduction = new ModelProduction($PDO); //$PDO est contenu dans le fichier 'connect.php'
    }

    /**
     * setListe traite la variable et la donne à getListe
     */
    function setListe($setlabo) {
        $setlabo = !empty ($setlabo) ? filter_var($setlabo, FILTER_SANITIZE_STRING) : NULL;
        $this->modelProduction->getListe($setlabo);
    }
}

$controlProd = new ControllerProd();
Et enfin le 3ème fichier, qui va effectuer tout ce qui ressort de mysql
class ModelProduction{
    
    private $db;

    function __construct($db) {
        $this->db = $db;
    }
    
    function getListe($getLabo){
        //requête pour lister des produits en fonction de la variable ci-dessus
    }
}
Mais le serveur ne reconnait pas l'objet $PDO :
Notice: Undefined variable: PDO in C:\wamp\www\integration\controller\controllerProd.php
Pourquoi ?
Merci,
«Le matin, quand il t’en coûte de te réveiller, que cette pensée te soit présente: c’est pour faire œuvre d’homme que je m’éveille.»
Marc Aurèle.

ViPHP
ViPHP | 2577 Messages

07 oct. 2011, 11:54

C'est un problème de portée de variable.
Il faut ajouter la ligne "global $PDO;" en début de script ou utiliser $GLOBALS['PDO'].
(enfin je crois^^)

ViPHP
xTG
ViPHP | 7331 Messages

07 oct. 2011, 12:02

En effet c'est de portée qu'il est question. Une class est isolée du reste.
Donc soit dans ton constructeur tu lui passes la variable, soit tu la places en global, soit tu fais ton require dans le constructeur.

Mammouth du PHP | 568 Messages

07 oct. 2011, 13:47

En effet c'est de portée qu'il est question. Une class est isolée du reste.
Donc soit dans ton constructeur tu lui passes la variable, soit tu la places en global, soit tu fais ton require dans le constructeur.
+1

Soit tu utilise un Singleton.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2011, 14:20

En effet c'est de portée qu'il est question. Une class est isolée du reste.
Donc soit dans ton constructeur tu lui passes la variable, soit tu la places en global, soit tu fais ton require dans le constructeur.
+1

Soit tu utilise un Singleton.
Attention, le but d'un singleton est de s'assurer de n'avoir qu'une instance de la classe. Pas d'y accéder facilement depuis n'importe où.
C'est en faisant ça qu'on commence à faire n'importe quoi.

Mais, toujours est-il que le conseil, dans ce contexte est bon, et que c'est la bonne solution
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
xTG
ViPHP | 7331 Messages

07 oct. 2011, 14:22

Dans son cas on ne peut juger pour le Singleton, on ne peut d'ailleurs souvent jamais juger sans avoir le cahier des charges.
Il ne nous a pas dit ce qu'il comptait exploiter.
Il a peut être besoin d'accéder à plusieurs sgbd pour un même traitement. ;)

Mais je plussoie pour l'exploitation d'un unique sgbd. :)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2011, 14:26

Ta précision est très utile, mais le cas de la base de données est un cas d'école qui se gère avec un Singleton ou un Multiton.
Le besoin est toujours le même, à savoir ne pas instancier 50 fois la connexion, et pouvoir y accéder simplement.

Après, ce n'est pas un soucis de cahier des charges, mais d'architecture logicielle : est-ce que le fait d'instancier un objet depuis un autre est une pratique tolérable ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 568 Messages

07 oct. 2011, 14:37

Attention, le but d'un singleton est de s'assurer de n'avoir qu'une instance de la classe. Pas d'y accéder facilement depuis n'importe où.
Oui, mais c'est tout de même plus propre que d'utiliser la syntaxe avec "global".

Et évidemment, s'il doit utiliser plusieurs bases, un Multiton sera de rigueur (et effectivement c'est le cahier des charges qui le dira).

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2011, 14:55

En fait, ce qui me gène, c'est cette habitude de dénaturer un concept pour le rendre juste pratique.
Utiliser le singleton pour remplacer un $_GLOBAL est pour moi une profonde mauvaise compréhension du design pattern, et surtout l'entrée à un code très couplé dans tout les sens et donc très monolithique.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
AB
ViPHP | 5818 Messages

07 oct. 2011, 15:03


Eléphant du PHP | 226 Messages

07 oct. 2011, 15:06

Ne vous battez pas, hein... :)
Honnêtement, j'ai déjà eu affaire au problème de portée de variable, mais dans ce cas-ci, ça ne me serait jamais venu à l’esprit (surtout le vendredi)
J'avais bien compris que déclarer une variable globale n'était pas bon. Et bien que cela fonctionne, je n'arrive pas à voir comment faire passer la variable dans le constructeur comme vous le conseiller.
function __construct($bdd) {
        $this->bdd = $PDO;
        $this->modelProduction = new ModelProduction($PDO);
    }
C'est la première fois que je déclare un objet dans un constructeur (je suis encore débutant en POO), mais initialiser une seconde fois l'objet PDO pour qu'il soit reconnu, je bloque...
«Le matin, quand il t’en coûte de te réveiller, que cette pensée te soit présente: c’est pour faire œuvre d’homme que je m’éveille.»
Marc Aurèle.

ViPHP
xTG
ViPHP | 7331 Messages

07 oct. 2011, 16:12

Merci pour le lien zeus, je connaissais pas ce pattern et il retient toute mon attention actuellement. :D

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2011, 16:15

C'est toujours plaisant de se rendre compte qu'on a progressé en 2 ans ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
AB
ViPHP | 5818 Messages

07 oct. 2011, 17:37

C'est toujours plaisant de se rendre compte qu'on a progressé en 2 ans ;)
Tu fais autrement aujourd'hui ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 oct. 2011, 17:51

Non, mais à l'époque, je considérais encore le Singleton comme un moyen de contourner $_GLOBALS ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer