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

Langage PHP Discussion :

[POO] Manipuler la connexion de base de données [PHP 5.2]


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 92
    Points : 77
    Points
    77
    Par défaut [POO] Manipuler la connexion de base de données
    Bonjour tout le monde,

    Je suis actuellement sur un projet personnel, et pour bien structurer mon système, je me suis décidé à utiliser la POO dans ce projet. Mais j'ai une petite question sur la manipulation de la connexion de la base de données.

    Par exemple, j'ai une class "user", dont le constructeur prend en paramètre l'identifiant de l'utilisateur. Et puis le programme lit, dans la base, les informations de l'utilisateur, et les stocke dans les attributs privés de l'objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class user{
        private $username;
        private $avatar;
        private $etc;
     
        public function __construct($_username){
        // Lecture de données
        }
    }
    Le problème est, comment est-ce que ma classe "user" accede à la connexion de la base de données? Est-ce qu'on peut passer le référence de la connexio au constructeur de la classe, like:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        public function __construct(&$database, $_username){
        // Lecture de données
        }
    J'ai vu sur le net, on m'a conseillé de créer une classe de base de données, et stocke le référence de la connexion dans un attribut statique. On n'aura toujours qu'une seule connexion.

    Mais normalement les classes sont définies dans de différents fichiers, et on doit les utiliser ensemble. Je ne vois pas trop comment résoudre ce problème.

    J'ai voulu mettre la connexion dans une variable global, mais apparemment ce n'est pas un bon choix non plus.

    Donc j'aimerais demander si quelqu'un a une idée. Pour que toutes les classes soient réutilisables et puissent accéder à la connexion de BD facilement.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 230
    Points
    20 230
    Par défaut
    En gros il y'a 3 écoles ,

    La première que tu évoques , ou on utilise une singleton (c'est le nom savant) de la bdd que l'on appelle dans chacune des classes qui en à besoin.
    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Class user
    {
        private oSql
        public function __construct(){
            $this->oSql = DBMysql::getInstance();    
        }
     
        public function methodeAvecAccessBdd(){
            $this->oSql->query('SELECT...');
        }
    }
    DBMysql étant bien entendu la class de gestionde base de données.

    La seconde solution est un peu du même accabit sauf que l'on passe l'objet mysql au constructeur de la classe en ayant besoin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public function __construct($sql){
            $this->oSql =$sql    
    }
    La dernière à mon avis à proscrire consiste à ouvrir une connexion dans chaque classe en ayant besoin. Du coup on se retrouve souvent avec de nombreuse instance de ta class Bdd et ce de manière inutile.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau membre du Club
    Inscrit en
    Novembre 2008
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    En ce qui concerne les classes stockées dans de différents fichiers, je te conseille de jeter un coup d'oeil sur la méthode magique __autoload ... En utilisant cette fonction tu peux définir une méthode pour aller chercher automatiquement le fichier correspondant à ta classe, sans avoir à déclarer des require dans chaque classe ou script... Bien entendu, cela implique que tes fichiers de classe respectent une convention de nommage, par exemple, "Nomdeclasse.php", "Nomdeclasse.classe.php", "classes/Nom.php", à toi de voir... Un des gros avantages est de pouvoir stocker les classes dans un répertoire bien séparé du reste du site, même en dehors du document root de ton site.

    En ce qui concerne le stockage de la connexion, le singleton est en effet le meilleur choix, puisque tu t'assures qu'une seule connexion soit créée !

  4. #4
    Membre expérimenté Avatar de riete
    Homme Profil pro
    DevWeb - Oléiculteur
    Inscrit en
    Avril 2006
    Messages
    1 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : DevWeb - Oléiculteur
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 193
    Points : 1 414
    Points
    1 414
    Par défaut
    @grunk
    Au risque de passer pour un béotien, je me hazarde à une question, car le sujet m'interesse.

    J'ai repris le plus simplement possible ton exemple auquel j'ai rajouté une Class DBMysql bidon. J'ai pris soin de rendre $oSQL public. Mais l'accès au membre oSql ne me retourne rien ?

    J'ai bien tenté de faire hériter User de DBMysql, mais rien de plus ???

    Peux tu éclairer ma lanterne merci ?
    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
    Class DBMysql{
     
    	public $instance = "#ressource";
     
    	public function getInstance(){
     
    		return $this->instance;
    	}
    }
     
    Class User{
     
        public $oSql;
     
        public function __construct(){
            $this->oSql = DBMysql::getInstance();
        }
     
        public function methodeAvecAccessBdd(){
            $this->oSql->query('SELECT...');
        }
    }
     
    $myDB = new DBMysql;
    $myUser = new User;
     
    // Acces Class
    echo "Direct: ".$myDB->getInstance()."<br>";
     
    // Acces static depuis user
    echo "Static: ".$myUser->oSQL."<br>";
    ----
    L'avenir appartient à ceux dont les salariés se lèvent tôt.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Novembre 2008
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 43
    Points : 38
    Points
    38
    Par défaut
    @riete : il manque le constructeur dans ta classe DBMySql, et getInstance doit s'assurer qu'il n'existe qu'une seule instance... $instance va contenir ton unique instance de la classe, et il te faut rajouter une variable interne $link qui sera accessible depuis des méthodes de la classe DBMysql qu'il te faut définir, et qui contiendra la ressource de connexion à la BDD.

    Donc :

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    <?php
     
    Class DBMysql {
     
    	// $instance correspond à l'unique instance de la classe qui peut exister
    	private static $instance = null;
    	// mettre en privé, seule la méthode getInstance doit pouvoir y accéder
    	// mettre aussi en static car tu n'instancies pas ta classe dans tes appels (utilisation du :: )
     
    	// la variable $link stocke la connexion, mais reste privée ! Elle sera exploitée par des méthodes du type query() à l'intérieur de la classe.
    	private $link;
     
     
    	// ton constructeur doit aussi être en privé, pour n'être accessible que de l'intérieur de la classe, par la méthode getInstance !
    	private function __construct()
    	{
    		$dblink = mysql_connect('host','user','pass');
    		$this->link = mysql_select_db('db',$dblink);
    	}
     
    	// getInstance doit aussi être statique pour être accessible sans qu'on instancie la classe
    	public static function getInstance()
    	{
    		$cls = __CLASS__; // On réupère le nom de cette classe par __CLASS_
    		if (self::$instance == null) self::$instance = new $cls(); // Si $instance n'existe pas, on la crée.
    		return self::$instance; // dans tous les cas, on retourne $instance.
    	}
     
    	// ensuite il faut définir des méthodes d'accès à la base, soit dans cette classe ou dans les classes exploitant cette connexion.
    	public function query($queryString)
    	{
    		// Logique SQL... mysql_query etc...
    	}
    }
     
    Class User{
     
        public $oSql;
     
        public function __construct(){
            $this->oSql = DBMysql::getInstance();
        }
     
        public function methodeAvecAccessBdd(){
            $this->oSql->query('SELECT...');
        }
    }
     
    $myDB = new DBMysql;
    $myUser = new User;
     
    // Acces Class
    echo "Direct: ".$myDB->getInstance()."<br>";
     
    // Acces static depuis user
    echo "Static: ".$myUser->oSQL."<br>"; 
     
    // Normalement tu devrais avoir la même ressource pour tes deux méthodes ci-dessus
    @grunk : c'est fait, je m'en suis rendu compte en me relisant ^^"

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 230
    Points
    20 230
    Par défaut
    Mistertbo à bien résumé, cependant si on voulait respecter le pattern singleton il faudrait passer getInstance en static
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 92
    Points : 77
    Points
    77
    Par défaut
    on utilise une singleton (c'est le nom savant) de la bdd que l'on appelle dans chacune des classes qui en à besoin
    Merci grunk, C'est exactement ce que j'ai fait. J'ai fait des recherches sur Google depuis hier soir, lol. C'est mon code:
    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
     
    private function database($db_server, $db_username, $db_password, $db_name){
    	//Si la base est déjà ouverte
    	if(self::$db_link != NULL)
    		@mysql_close(self::$db_link);
     
    	$this->db_server	= $db_server;
    	$this->db_username	= $db_username;
    	$this->db_password	= $db_password;
    	$this->db_name		= $db_name;
     
    	// Connecter à la base
    	try{
    		self::$db_link = @mysql_connect($this->db_server, $this->db_username, $this->db_password);
    		if(self::$db_link === FALSE)
    			throw new except("Echec de connexion");
     
    		if(mysql_select_db($this->db_name, self::$db_link) === FALSE)
    			throw new except("Echec de selection de bdd");
    	}catch(except $exc){
    		self::$db_link = NULL;
    		$exc->print_error_msg($exc);
    	}
    }
     
    public static function get_instance($db_server, $db_username, $db_password, $db_name){
    	$database = new database($db_server, $db_username, $db_password, $db_name);
    	if(self::$db_link == NULL)
    		return NULL;
    	return $database;
    }
    J'ai créé aussi une classe d'exception, c'est la "except".
    Et puis j'ai créé une classe application, qui sert à faire de la communication entre la connexion de bdd et les autres classes.

    Toutes les grosses manipulations(update, insert ... etc.) sont regroupées dans cette classe. j'ai des méthodes genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    get_user($username);
    get_user($username, $password); // avec une __call()
    etc.
    je te conseille de jeter un coup d'oeil sur la méthode magique __autoload ...
    Oui, mistertbo, je viens de trouver ça dans le doc de PHP, il est vraiment très puissant, cette fonction magique. Maintenant je n'ai plus besoin de taper 50 require_once au début de chaque fichier.

    C'est la fonction autoload que j'ai créé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function __autoload($libname){
    	$directories = array('inc');
    	$prefixes = array('class');
     
    	foreach($directories as $directory){
    		foreach($prefixes as $prefix){
    			$filename = "{$directory}/{$prefix}.{$libname}.php";
    			if(file_exists($filename) && is_file($filename) && is_readable($filename))
    				require_once($filename);
    		}
    	}
    }
    Merci à vous ! Bonne journée!

  8. #8
    Membre expérimenté Avatar de riete
    Homme Profil pro
    DevWeb - Oléiculteur
    Inscrit en
    Avril 2006
    Messages
    1 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : DevWeb - Oléiculteur
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 193
    Points : 1 414
    Points
    1 414
    Par défaut
    merci Mistertbo
    Bonne leçon pour moi
    ----
    L'avenir appartient à ceux dont les salariés se lèvent tôt.

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

Discussions similaires

  1. Connexion à une base de donnée en POO via file.ini
    Par Eric5031 dans le forum Langage
    Réponses: 3
    Dernier message: 16/04/2015, 10h46
  2. [PHP 5.2] POO et connexion à une base de données dans une fonction
    Par tolwin dans le forum Langage
    Réponses: 5
    Dernier message: 09/11/2012, 11h39
  3. [POO] Connexion à une base de données
    Par merlubreizh dans le forum Langage
    Réponses: 2
    Dernier message: 30/01/2008, 10h13
  4. [POO] Classe de connexion à une base de données
    Par iwf-fr dans le forum Langage
    Réponses: 3
    Dernier message: 13/11/2007, 13h55
  5. Réponses: 3
    Dernier message: 29/03/2004, 18h02

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