Partage
  • Partager sur Facebook
  • Partager sur Twitter

Utilisation de PDO dans une classe

souci de portabilité de l'objet

    30 juillet 2010 à 10:23:08

    Bonjour,

    Je me mets à PDO. J'ai un fichier pour établir la connexion à la BDD.

    config.php
    <?php
    // fichier contenant les informations pour se connecter
    $fichier = 'config/sql.ini';
    if(file_exists($fichier)) {
    $config = parse_ini_file($fichier, true);
    
    $moteur = $config['SQL']['moteur'];
    $hote   = $config['SQL']['hote'];
    $login  = $config['SQL']['login'];
    $mdp    = $config['SQL']['mdp'];
    $base   = $config['SQL']['base'];
    
    	try {
    	$bdd = new PDO($moteur .':host='. $hote .';dbname='. $base, $login, $mdp);
    	$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    	} catch (Exception $e) {
    	die('Erreur : '. $e->getMessage());
    	}
    }
    ?>
    


    Ensuite je souhaite faire des requêtes dans une classe existante.

    personne.php
    <?php
    class personne {
    	var $id_pers;
    	var $service;
    	var $nom;
    	var $prenom;
    
    	function personne($login) {
    	$requete = 'SELECT * FROM personnes WHERE login = "'.$login.'"';
    	$resultat = $bdd->query($requete);
    // ...
    ?>
    


    Est-ce que si dans config.php j'englobe tout dans une classe et qu'après dans l'autre fichier je fais extends Maclasse il aura accès à $bdd ?

    Et là il ne connaît pas l'objet $bdd même avec l'include du fichier de config. Des idées ?

    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      30 juillet 2010 à 10:28:42

      Ca t'affiche undefined variable : bdd ?
      $bdd n'est pas définie dans la classe.

      Essaye de rajouter ça :
      <?php
      class personne {
      	var $id_pers;
      	var $service;
      	var $nom;
      	var $prenom;
      
      	function personne($login) {
      	$requete = 'SELECT * FROM personnes WHERE login = "'.$login.'"';
      	global $bdd;
              $resultat = $bdd->query($requete);
      // ...
      ?>
      
      • Partager sur Facebook
      • Partager sur Twitter
        30 juillet 2010 à 10:30:05

        Apparemment ça fonctionne avec global mais j'aimerais ne pas l'utiliser car ce n'est pas propre.

        D'autres suggestions ?
        • Partager sur Facebook
        • Partager sur Twitter
          30 juillet 2010 à 10:34:08

          Ah merci pour l'astuce car moi aussi j'avais le meme problème ...
          • Partager sur Facebook
          • Partager sur Twitter
            30 juillet 2010 à 10:49:49

            Au pire tu peux créer une classe connexion avec l'attribut $bdd en static :
            <?php
            
            class Connexion {
                
                public static function bdd() {
                    // fichier contenant les informations pour se connecter
                    $fichier = 'config/sql.ini';
                    if(file_exists($fichier)) {
            	    $config = parse_ini_file($fichier, true);
            	
            	    $moteur = $config['SQL']['moteur'];
            	    $hote   = $config['SQL']['hote'];
            	    $login  = $config['SQL']['login'];
            	    $mdp    = $config['SQL']['mdp'];
            	    $base   = $config['SQL']['base'];
            	
            	    try {
            	        $bdd = new PDO($moteur .':host='. $hote .';dbname='. $base, $login, $mdp);
            	        $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            	    } catch (Exception $e) {
            	    die('Erreur : '. $e->getMessage());
            	    }
                        return $bdd;
                    }
                }
            }
            
            
            
            class personne {
            	var $id_pers;
            	var $service;
            	var $nom;
            	var $prenom;
            
            	function personne($login) {
            	$requete = 'SELECT * FROM personnes WHERE login = "'.$login.'"';
            	$query = Connexion::bdd()->query($requete);
            	
                    $resultat = $query->fetch();
            	}
            }
            ?>
            

            A modifier car j'ai fait un vulgaire copier/coller, mais l'idée est là.
            Je ne sais pas si ça fonctionne j'ai rarement fait de la POO en PHP, mais à tester si ça te convient davantage.
            • Partager sur Facebook
            • Partager sur Twitter
              30 juillet 2010 à 14:10:17

              Bonjour,

              Le plus propre en OO est de passé l'objet de connexion dans le constructeur de tes classes qui l'utilisent.

              <?php
              class Database {
                private $instance = null;
              
                public function __construct($pDSN, $pUserName, $pPassword) {
                  $this->instance = new PDO($pDSN, $pUserName, $pPassword);
                }
              
                public function getInstance() {
                  return $this->instance;
                }
              }
              
              class Personne {
                private $nom = null;
                private $prenom = null;
                private $database = null;
              
                public function __construct($pNom, $pPrenom, $pDatabase) {
                  $this->nom = $pNom;
                  $this->prenom = $pPrenom;
                  $this->database = $pDatabase;
                }
              
                public function save() {
                  $this->database->query('INSERT INTO ...');
                }
              }
              


              ++
              • Partager sur Facebook
              • Partager sur Twitter
                30 juillet 2010 à 14:15:45

                Je dirait même pour ceci
                public function __construct($pNom, $pPrenom, $pDatabase) {
                $this->nom = $pNom;
                $this->prenom = $pPrenom;
                $this->database = $pDatabase;
                }

                remplacer par ceci :

                public function __construct($pNom, $pPrenom, Database $pDatabase) {
                $this->nom = $pNom;
                $this->prenom = $pPrenom;
                $this->database = $pDatabase;
                }


                comme sa le dernier argument on attent un objet de type Database comme sa on est sur de na pas mettre autre chose comme un int ou array ;)

                mais bon le plus simple si tu travaille qu'avec des classe c'est d'herité une classe de PDO class maClass extends PDO ;)
                • Partager sur Facebook
                • Partager sur Twitter
                Infoxp ici depuis 2007
                  30 juillet 2010 à 14:25:03

                  Voilà j'ai rectifié le parse error et ça fonctionne, tout du moins chez moi.
                  Ainsi tu n'as pas besoin d'instancier d'object pour établir une connexion.
                  Tu peux aussi faire ceci dans tes classes pour ne pas être dépaysagé :
                  $bdd = Connexion::bdd();
                  Puis faire ta requête habituelle.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 juillet 2010 à 14:45:44

                    Bon désolé là je comprends plus rien, je suis pas habitué à l'objet.
                    Je vous explique ce que je souhaite :
                    - avoir une classe qui gère la connexion avec MySQL (PDO) avec une méthode qui exécute les requêtes SQL (query()).
                    - je veux pouvoir y avoir accès depuis n'importe où pour exécuter mes requêtes, que ce soit dans une classe ou non.

                    Voici mon code :

                    config.php
                    <?php
                    class Connexion extends PDO {
                    
                    	private $bdd, $moteur, $hote, $login, $mdp, $base;
                    
                    	public function __construct() {
                    	$fichier = 'config/sql.ini';
                    		if(file_exists($fichier)) {
                    		$config = parse_ini_file($fichier, true);
                    
                    		$this->moteur = $config['SQL']['moteur'];
                    		$this->hote   = $config['SQL']['hote'];
                    		$this->login  = $config['SQL']['login'];
                    		$this->mdp    = $config['SQL']['mdp'];
                    		$this->base   = $config['SQL']['base'];
                    
                    			try {
                    			$this->bdd = new PDO($this->moteur .':host='. $this->hote .';dbname='. $this->base, $this->login, $this->mdp);
                    			$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                    			} catch(Exception $e) {
                    			die('Erreur : '. $e->getMessage());
                    			}
                    		}
                    	}
                    
                    	public function getBdd() {
                    	return $this->bdd;
                    	}
                    	
                    	public function requete($requete) {
                    	$this->bdd->query($requete);
                    	}
                    }
                    ?>
                    


                    personne.php
                    <?php
                    class personne extends Connexion {
                    
                    	public function personne($login) {
                    	$requete = "SELECT * FROM personnes WHERE login = '".$login."'";
                    	$resultat = Connexion::getBdd()->requete($requete);
                            //...
                            }
                    }
                    ?>
                    


                    L'erreur est : "Fatal error: Call to a member function requete() on a non-object"

                    Je n'arrive pas à exécuter ma requête depuis une autre classe.

                    Merci...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 juillet 2010 à 14:51:23

                      Edit : rien dit

                      En revanche ceci est tout à fait normal
                      Tu ne declare pas l'objet pour construire la connexion :

                      public function personne($login) {
                      $requete = "SELECT * FROM personnes WHERE login = '".$login."'";
                      $resultat = Connexion::getBdd()->requete($requete);
                      //...
                      }

                      =>

                      public function personne($login) {
                      $connexion = new Connexion();

                      $requete = "SELECT * FROM personnes WHERE login = '".$login."'";
                      $resultat = $connexion->getBdd()->requete($requete);
                      //...
                      }

                      et aussi retire le extends Connexion de ta classe personne car t'en a aucunne utilité dans ton cas ;)
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Infoxp ici depuis 2007
                        30 juillet 2010 à 14:55:19

                        Tout simplement car tu n'as pas instancié d'objet et tu n'as pas gardé ma fonction en statique.

                        Pour accéder à la classe mère il faut utiliser parent::, et pas Connexion:: (qui sert seulement pour les méthodes statiques).
                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 juillet 2010 à 14:58:45

                          Re,

                          Citation

                          personne extends Connexion



                          D'un point de vue orienté objet, tu trouves vraiment qu'un personne EST une connexion ? Parce que c'est ce que tu écris là. :-°

                          ++
                          • Partager sur Facebook
                          • Partager sur Twitter
                            30 juillet 2010 à 15:04:04

                            Attention ! Nullement besoin d'une classe pour gérer la connexion à la base de donnée quand on utilise PDO !
                            La connexion doit se faire en dehors de toute classe, en début de script.
                            Et comme l'indique jordan, on transmet l'objet PDO aux classes en ayant besoin via leur constructeur.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              2 août 2010 à 11:06:22

                              J'ai toujours des soucis dans l'utilisation de PDO...

                              Ma classe qui gère PDO (je préfère en avoir une) :
                              <?php
                              class Connexion extends PDO {
                              
                              	private $bdd, $moteur, $hote, $login, $mdp, $base;
                              
                              	public function __construct() {
                              	$fichier = 'config/sql.ini';
                              		if(file_exists($fichier)) {
                              		$config = parse_ini_file($fichier, true);
                              
                              		$this->moteur = $config['SQL']['moteur'];
                              		$this->hote   = $config['SQL']['hote'];
                              		$this->login  = $config['SQL']['login'];
                              		$this->mdp    = $config['SQL']['mdp'];
                              		$this->base   = $config['SQL']['base'];
                              
                              			try {
                              			$this->bdd = new PDO($this->moteur .':host='. $this->hote .';dbname='. $this->base, $this->login, $this->mdp);
                              			$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                              			} catch(Exception $e) {
                              			exit('Erreur : '. $e->getMessage());
                              			}
                              		}		
                              	}
                              	
                              	public function requete($requete) {	
                              	return $this->bdd->query($requete) or exit(print_r($this->bdd->errorInfo()));
                              	}
                              	
                              	public function fetch($resultat) {
                              	return $resultat->fetch();
                              	}
                              	
                              	public function compteur($resultat) {
                              		if(is_object($resultat)) {
                              		echo 'ok';
                              		} else {
                              		echo 'pas ok';
                              		}
                              	return $resultat->rowCount();
                              	}
                              	
                              	public function close($resultat) {
                              	return $resultat->closeCursor();
                              	}	
                              }
                              ?>
                              


                              Maintenant dans la page qui sert à loguer les membres j'essaye de l'utiliser :
                              <?php
                              session_start();
                              include('../includes/fonctions.php');
                              include('../config/config.php');
                              
                              $connexion = new Connexion();
                              $login = $_POST['login'];
                              $pass = $_POST['mdp_windows'];
                              
                              $requete = "SELECT id_pers, login, mdp_windows, cookie FROM personnes WHERE login = '". $login ."' AND mdp_windows = '". $pass ."'";
                              $resultat = $connexion->requete($requete);
                              
                              // $resultat = requete($requete);
                              if($connexion->compteur($resultat) == 1) { // si le login correspond au mot de passe
                              	$donnees = $connexion->fetch($resultat);
                              	// ...
                              	$path = '/geslan2/';
                              } else {
                              }
                              header('Location: ../');
                              ?>
                              


                              Citation

                              pas ok
                              Fatal error: Call to a member function rowCount() on a non-object in C:\wamp\www\geslan2\config\config.php on line 39



                              Donc mon $resultat n'est pas un objet, pourquoi ?
                              J'ai fait un var_dump est c'est un bool(true). Pourtant :

                              Citation : php.net

                              PDO::query() retourne un objet PDOStatement, ou FALSE si une erreur survient.


                              Merci de m'aider...
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Utilisation de PDO dans une classe

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown