Page 1 sur 1

Portée global de connexion

Posté : 06 juil. 2009, 10:27
par Yosh
Bonjour à tous,

J'ai un petit soucis avec le protée de ma connexion PDO.

j'utilise une classe db qui instancie une connexion via pdo à ma base, et je souhaite créer une classe utilisant cette connexion afin de faire des requêtes.

Ma classe utilisant PDO
<?php
	//require_once('library/config.php');
	
	class db {	
		/*** Declare instance ***/
		private static $instance = NULL;
	
		/**
		*
		* the constructor is set to private so
		* so nobody can create a new instance using new
		*
		*/
		private function __construct() { }
		
		/**
		*
		* Like the constructor, we make __clone private
		* so nobody can clone the instance
		*
		*/
		private function __clone(){	}
		
		/**
		*
		* Return DB instance or create intitial connection
		*
		* @return object (PDO)
		*
		* @access public
		*
		*/
		public static function getInstance() {		
			if(!self::$instance) {
				if(MODE_PERSISTANT) {
					//avec persistance
					self::$instance = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWORD, array(
							PDO::ATTR_PERSISTENT => true
					));
				} else {
					//sans persistance
					self::$instance = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWORD);
				}
				
				self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			}
			return self::$instance;
		}
	}
	
	try {
		$db = db::getInstance();
	} catch(PDOException $e) {
		if(DEBUG) {
			echo 'Erreur : '.$e->getMessage();	
		} else {
			echo "Une erreur est survenu lors de la connexion à la base de données.";
		}
		die();
	}
?>
Ma seconde class
<?php
	<?php
	require_once('config.php');
	require_once('db.class.php');
	
	class plateforme_logistique {
		
		private $plateforme_id;
		private $plateforme_nom;
		private $plateforme_adresse;
		private $plateforme_code_postal;
		private $plateforme_ville;
		private $plateforme_tel;
		private $plateforme_fax;
		private $plateforme_date_creation;
		private $plateforme_date_modification;
		
		private $error = array();
		
		public function __construct() {			
			$this->plateforme_id = NULL;
			$this->plateforme_nom = NULL;
			$this->plateforme_adresse = NULL;
			$this->plateforme_code_postal = NULL;
			$this->plateforme_ville = NULL;
			$this->plateforme_tel = NULL;
			$this->plateforme_fax = NULL;
			$this->set_date_creation();
			$this->plateforme_date_modification = NULL;
		}
		
		public function __destruct() {}
		
		public function __clone() {}
		
		public function set_id($plateforme_id) { $this->plateforme_id = $plateforme_id; }		
		public function set_nom($plateforme_nom) { $this->plateforme_nom = $plateforme_nom; }
		public function set_adresse($plateforme_adresse) { $this->plateforme_adresse = $plateforme_adresse; }
		public function set_code_postal($plateforme_code_postal) { $this->plateforme_code_postal = $plateforme_code_postal; }
		public function set_ville($plateforme_ville) { $this->plateforme_ville = $plateforme_ville; }
		public function set_tel($plateforme_tel) { $this->plateforme_tel = $plateforme_tel; }
		public function set_fax($plateforme_fax) { $this->plateforme_fax = $plateforme_fax; }
		public function set_date_creation() { $this->plateforme_date_creation = date("Y-m-d H:i:s"); }
		public function set_date_modification($plateforme_date_modification) { $this->plateforme_date_modification = $plateforme_date_modification; }
		
		public function insert() {
			//global $db;
			
			//query
			$sql = "INSERT INTO plateforme_logistique (plateforme_nom, plateforme_adresse, plateforme_code_postal, plateforme_ville, plateforme_tel, plateforme_fax) VALUES (:plateforme_nom, :plateforme_adresse, :plateforme_code_postal, :plateforme_ville, :plateforme_tel, :plateforme_fax);";					
			
			//prepare sql
			$stmt = $db->prepare($sql);
			
			//prepare param
			/*$stmt->bindParam(":plateforme_nom", $this->plateforme_nom, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_adresse", $this->plateforme_adresse, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_code_postal", $this->plateforme_code_postal, PDO::PARAM_STR, 5);
			$stmt->bindParam(":plateforme_ville", $this->plateforme_ville, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_tel", $this->plateforme_tel, PDO::PARAM_STR, 10);
			$stmt->bindParam(":plateforme_fax", $this->plateforme_fax, PDO::PARAM_STR, 10);
			$stmt->bindParam(":plateforme_date_creation", date("Y-m-d H:i:s"));
			
			//exec sql
			return $stmt->execute();*/
		}
		
		public function update() {
			//query
			$sql = "UPDATE plateforme_logistique SET 
				plateforme_nom = :plateforme_nom,
				plateforme_adresse = :plateforme_adresse,
				plateforme_code_postal = :plateforme_code_postal,
				plateforme_ville = :plateforme_ville,
				plateforme_tel = :plateforme_tel,
				plateforme_fax = :plateforme_fax 
				WHERE plateforme_id = :plateforme_id;";
			
			//prepare sql
			$stmt = $db->prepare($sql);
			$stmt->bindParam(":plateforme_id", $plateforme_id, PDO::PARAM_INT);
			$stmt->bindParam(":plateforme_nom", $plateforme_nom, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_adresse", $plateforme_adresse, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_code_postal", $plateforme_code_postal, PDO::PARAM_STR, 5);
			$stmt->bindParam(":plateforme_ville", $plateforme_ville, PDO::PARAM_STR);
			$stmt->bindParam(":plateforme_tel", $plateforme_tel, PDO::PARAM_STR, 10);
			$stmt->bindParam(":plateforme_fax", $plateforme_fax, PDO::PARAM_STR, 10);
			//exec sql
			$stmt->execute();
		}
		
		public function delete() {
			
		}
		
		public function get_liste() {
			
		}
	}
	
	$test = new plateforme_logistique();
	$test->set_nom("test");
	$test->set_adresse("adresse");
	$test->set_code_postal("01000");
	$test->set_ville("bourg");
	$test->set_tel("test");
	
	//var_dump($test);
	if($test->insert()) {
		echo "insert ok";
	} else {
		echo "insert pas ok";
	}
?>
Pour se faire, je suis obliger de déclarer ma connexion en global dans la méthode de ma classe afin d'y avoir accès et je trouve ça moyen...

Je déclare avec le code suivant à l'intérieur de ma méthode insert()
global $db;
Existe-il un moyen propre / différent de faire cela?

EDIT:

l'autre solution que j'ai trouvé est d'étendre ma seconde class avec la class db et de faire dans chaque méthode
$db = parent::getInstance();
Mais je ne sais pas si c'est mieux.

Posté : 06 juil. 2009, 12:58
par mojorisin
Bonjour,
vous utilisez un singleton pour instancier votre classe db. il vous suffit de l'include puis d'appele votre instance quand vous en avez besoin : $db = db::getInstance();

Posté : 06 juil. 2009, 14:37
par Yosh
ok,

mais est-ce la meilleur solution...connu et reconnu?

Posté : 07 juil. 2009, 09:47
par mojorisin
Bonjour,
c'est une solution parmis d'autres comme l'injection de la classe db dans la méthode par exemple function myMethod(db $db){}

C'est en tout cas plus propre qu'un global :)

Posté : 07 juil. 2009, 14:07
par AB
Bonjour,
c'est une solution parmis d'autres comme l'injection de la classe db dans la méthode par exemple function myMethod(db $db){}

C'est en tout cas plus propre qu'un global :)
++
Pas mieux. C'est le global qu'il faut éviter et les singletons sont souvent employés dans ce cas.

Posté : 07 juil. 2009, 16:47
par Yosh
Merci à vous.

Re: Portée global de connexion

Posté : 05 août 2009, 00:00
par globule
Existe-il un moyen propre / différent de faire cela?

EDIT:

l'autre solution que j'ai trouvé est d'étendre ma seconde class avec la class db et de faire dans chaque méthode
$db = parent::getInstance();
Mais je ne sais pas si c'est mieux.[/quote]
Personnellement, je préfère garder ma classe DB séparée, quitte à la stocker dans mes autres classes :
$this->db = database::getInstance;

Ainsi toutes mes classe y ont accès et je ne risque pas de surcharger une de mes méthodes database... :wink:
Sinon le global est une option fréquemment utilisée.

Re: Portée global de connexion

Posté : 05 août 2009, 07:39
par thehawk
Le global rend le debug beaucoup plus compliqué ;p (Mais où est cette variable déjà .... 2000 lignes plus loins ah oui ici :))


Donc le singleton est une bonne solution

Re: Portée global de connexion

Posté : 05 août 2009, 09:35
par AB
Le global rend le debug beaucoup plus compliqué ;p (Mais où est cette variable déjà .... 2000 lignes plus loins ah oui ici :))


Donc le singleton est une bonne solution
Tu as raison d'insister, le singleton est une bien meilleure solution qu'un global et c'est très souple d'emploi donc tout à fait adapté :wink:

Un exemple basique
class connect_bdd {

		private static $instance;
			
			private function __construct() {
			
				require_once('fichier_des_donnees_de_connexion');
				mysql_select_db($database, $connection);	

			}
			
			public static function getInstance() {
			
				if(self::$instance == NULL) self::$instance = new connect_bdd;
			}	 
}

connect_bdd::getInstance();

Re: Portée global de connexion

Posté : 05 août 2009, 18:12
par Number
Salut à tous,

Je rebondis sur cette question car je me la suis posée aussi ( ici ).

L'idée du singleton est pas mal, mais que faire lorsque notre class d'accès a la base de donnée permet de se connecter à plusieurs base ?

L'idée tombe à l'eau (Une instance par base de donnée) et donc, l'idée de passer l'identifiant a la class peut être retenue ?

Est-ce propre ? (Vu que je vois que vous parler tous du singleton )

Merci

Re: Portée global de connexion

Posté : 05 août 2009, 19:15
par zeus
Pour répondre à ce besoin, tout en gardant la souplesse du design pattern Singleton, il existe un autre design pattern : le Multiton.

En gros, tu gardes le principe du Singleton, mais en donnant un identifiant.

Voici un exemple codé :
class connect_bdd
{
	private static $instance = array();
                        
	private function __construct($db_name) 
	{
		require_once('fichier_des_donnees_de_connexion');
			
		// Permet de verifier que la base de donnees demandee existe
		if( !array_key_exists($db_name, $database) )
			throw new Exception('[connect_bdd] given database name "'.$db_name.'" is not configured');
			
		mysql_select_db($database[$db_name], $connection);        
	}
	
	public static function getInstance($db_name) 
	{
		// Si l'instance de connexion à la base de donnees n'existe pas, creation puis ajout à la liste des instances
		if( !array_key_exists($db_name, self::$instance) )
		{
			self::$instance = new connect_bdd($dbname);
		}
		
		return self::$instance[$db_name];
	}        
}

connect_bdd::getInstance('db1');
connect_bdd::getInstance('db2');
connect_bdd::getInstance('db1');

Re: Portée global de connexion

Posté : 05 août 2009, 20:04
par Number
Merci beaucoup, j'ai répondu sur l'autre sujet..