Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/11/2010, 22h23   #1
Membre du Club
 
xavier ruhlmann
Inscription : novembre 2005
Messages : 48
Détails du profil
Informations personnelles :
Nom : xavier ruhlmann
Âge : 40

Informations forums :
Inscription : novembre 2005
Messages : 48
Points : 42
Points : 42
Envoyer un message via MSN à zave
Par défaut Porté de la variable d'instanciation d'un objet PDO

Bonjour

Je suis entrain de me remettre au PHP et au passage j'en profite pour dépoussiéré mes connaissances. Ne connaissant pas trop PDO, je m'exerce à bien l'utilisé et j'ai un petit soucis.

J'ai deux fonctions: la première pour me connecter à ma BDD

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
function connectBdd()
		{
			try
			{
				$connexion = new PDO('mysql:host=localhost;dbname=basetest', 'root', '') ;
				$connexion->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
				$connexion->exec('SET NAMES utf8');
			}
			catch (Exception $e)
			{
				echo 'Erreur : '.$e->getMessage().'<br />';
				echo 'N° : '.$e->getCode();
				die();
			}
			return $connexion;
		}
une deuxième pour récupérer une valeur

Code :
1
2
3
4
5
6
7
8
 
function retourneValeur($id)
		{
			//$bdd = connectbdd();			
			$reponse = $bdd->query('SELECT * FROM test WHERE id='.$id );
			$donnees = $reponse->fetch(PDO::FETCH_ASSOC);
			return $donnees['nom'];
		}
Avant avec mysqli, je mettais ma fonction pour me connecter à ma base, ensuite, je pouvais faire des requêtes dans le reste de mon script sans problème.

j'aurai pu faire avec mysql:

fonction connectbdd(), pour me connecter à la BDD
placer dans la variable $var la valeur de retour de la fonction retourneValeur()

Si je suis cette logique avec PDO, ça donne ceci:

Code :
1
2
3
$bdd = connectbdd();
$var = retourneValeur(2);
echo $var;
Pour que ça fonctionne je suis obligé de mettre l'appel à la fonction $bdd = connectBdd(); , dans la fonction retourneValeur().

Ca fonctionne donc c'est déjà ça , mais si je dois utiliser plusieurs fonctions récupérant ou insérant des données dans la BDD, je dois à chaque fois utiliser la fonction de connexion.

Peut instancier la connexion grâce à une fonction qu'une seule fois dans la page du script?

Ma façon de faire n'est peut être pas correct, PDO s'utilise peut être différemment?

Merci d'avance, pour quelques explications qui m'aideront à mieux utilise PDO
zave est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2010, 22h43   #2
Membre Expert
 
Avatar de gene69
 
Inscription : janvier 2006
Messages : 951
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : janvier 2006
Messages : 951
Points : 1 063
Points : 1 063
Citation:
Peut instancier la connexion grâce à une fonction qu'une seule fois dans la page du script?
oui même je peux te le recommander. Généralement on met $connexion dans une variable (ou un attribut d'une classe) pis on l'initialise au démarage de la page pis on n'y touche plus jusqu'à la fin du script.

apres soit tu le passe $connexion dans tes fonctions qui appellent la db, méthode naïve, soit tu décretes que tu définies $connexion en dehors de toute fonction (cad dans l'espace global) et tu demandes explicitement dans une fonction utilisatrice de la base de donnée de confondre $connexion définie localement avec la variable $connexion définie globalement. Tu utilises alors le mot clé global.

je pense que ceci n'est pas spécifique à PDO
__________________
PHP fait nativement la validation d'adresse électronique Vous êtes perdu en PHP? rassurez-vous ici (en)
Utilisez le bouton résolu!
gene69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2010, 04h29   #3
Membre Expert
 
Inscription : septembre 2010
Messages : 1 230
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 230
Points : 1 550
Points : 1 550
Ouais en même temps une variable globale pour faire une connexion, c'est moyennement élégant. Perso je préfère une méthode statique pour pouvoir appeler la fonction de connexion autant de fois que je le souhaite tout en ne l'instanciant qu'une seule fois.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2010, 06h35   #4
Membre du Club
 
xavier ruhlmann
Inscription : novembre 2005
Messages : 48
Détails du profil
Informations personnelles :
Nom : xavier ruhlmann
Âge : 40

Informations forums :
Inscription : novembre 2005
Messages : 48
Points : 42
Points : 42
Envoyer un message via MSN à zave
Bonjour

tout d'abord merci d'avoir pris le temps de me répondre. je m'aperçois que tout qu'a cause de tout ce temps passé sans manier PHP, je suis rouillé.

Avant avec mysql j'aurai écrit ce code et il aurait fonctionné:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
function dbConnect()
{
	mysql_connect('localhost', 'root','');
	mysql_select_db('basetest');
}
 
function retourneValeur($id)
{
	$requete = mysql_query('SELECT * FROM test WHERE id='.$id );
	$resultat = mysql_fetch_assoc($requete);
	return $resultat['nom'];
}
dbConnect();
$var = retourneValeur(1);
echo $var;
?>
Si je suis cette logique avec PDO voir exemple de mon premier post ça ne fonctionne pas, il me faut mettre l'appel de la fonction de connexion dans ma fonction retourneValeur(). Ca fonctionne mais ça ne me parait pas satisfaisant.

J'ai pensé à mettre global à ma variable d'instance de PDO, je dois pas être doué ça fonctionne pas.

Etendre PDO dans un singleton je connais mais je veux rester au plus simple, je mets la POO de coté pour cet exercice.

Après réflexions et quelques essais, j'ai trouvé une autre solution, la voici:

Code :
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
<?php
Function connectBdd()
{
	try
	{
		$connexion = new PDO('mysql:host=localhost;dbname=basetest', 'root', '') ;
		$connexion->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
		$connexion->exec('SET NAMES utf8');
	}
	catch (Exception $e)
	{
		echo 'Erreur : '.$e->getMessage().'<br />';
		echo 'N° : '.$e->getCode();
		die();
	}
	return $connexion;		
}
 
function retourneValeur($id,$bdd)
{
	//$bdd = connectbdd();			
	$reponse = $bdd->query('SELECT * FROM test WHERE id='.$id );
	$donnees = $reponse->fetch(PDO::FETCH_ASSOC);
	return $donnees['nom'];
}
 
$bdd = connectbdd();
$var = retourneValeur(2, $bdd);
echo $var;
?>
Vu que le problème en fait c'est une histoire de porté de variable, en passant en paramètre, ma variable d'instance de PDO à ma fonction retourneValeur, ça fonctionne, c'est déjà mieux que ma 1ere solution, mais ça me laisse encore une impression de crade.

A part la solution global y a t'il d'autres possibilités?
zave est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2010, 07h47   #5
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Salut

Il faudrait que tu évite de tirer une mauvaise conclusion dans cette affaire, et du coup te fâcher avec la POO (PDO entre autre) alors que ça na pas de rapport directe.


Dans le fond, c'est l'inverse.
Faut savoir qu'avec les fonctions mysql_*, donc comme tu faisais anciennement, ceci offrait effectivement un certain confort, car lorsqu'on faisait une connexion, MySQL conservait en mémoire cette connexion.
Au bout, un simple appel à mysql_query() faisait en quelque sorte que l'on reprenait la même connexion.
Il fallait juste éviter de fermer (mysql_close) la connexion pour justement éviter de reconnecter.

D'ailleurs, regarde ton ancien code, dans la fonction retourneValeur($id), nulle part tu fait allusion à une variable liée à une connexion.
Il n'y a aucun problème de portée à ce niveau par ce qu'il n'y a pas de référence à aucune variable de connexion.
Par contre, si lors d'un appel à cette fonction $id existe mais n'est pas "passé" en argument dans la fonction, là cette fois tu auras un problème de portée sur cette variable $id, exactement la même que tu rencontre actuellement avec $bdd.


Actuellement, avec PDO on ne retrouve pas cette fonctionnalité là, ce confort de connexion conservée en permanence.
Au bout, tu ne fait que rencontrer un problème de portée qui est exactement la même dans n'importe quelle fonction, la même qu'il y a pour $id.
Par défaut, que ce soit dans une fonction ou une méthode de classe, une variable a une portée locale, donc uniquement dans la fonction.

Dis toi que finalement il n'y a rien d'extraordinaire, et ce n'est pas du tout lié à la POO ou PDO, tu ne fais que revenir dans un contexte normal.
C'est avant qui n'était pas si normal que ça.


Il y a plusieurs solutions pour résoudre cela :
1/ Soit transmettre la variable Objet $bdd en paramètre, comme actuellement.
2/ Soit déclarer $bdd en global dans la fonction.
3/ Soit créer une classe PDO dérivée, avec une méthode static qui retournera un Objet PDO, genre MyPDO::getInstance() qui sera à faire dans la fonction.

Il peut en avoir d'autres, mais c'est souvent ces 3 là qui sont retenues.

A titre personnel, j'ai un petit penchant pour la 3ème, appel à une méthode statique.
De même que la solution "crade" comme tu dis, ce serait plutôt la 2ème, en global (sans vouloir blesser qui que ce soit).
La 1ère n'est pas moche, les choses peuvent très bien se concevoir ainsi.


Prend le temps de faire des recherche sur le Net (le forum PDO entre autre) avec des mots genre PDO singleton.
Même si un singleton ne s'impose pas, c'est tout de même très souvent la solution choisie.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2010, 11h35   #6
Membre du Club
 
xavier ruhlmann
Inscription : novembre 2005
Messages : 48
Détails du profil
Informations personnelles :
Nom : xavier ruhlmann
Âge : 40

Informations forums :
Inscription : novembre 2005
Messages : 48
Points : 42
Points : 42
Envoyer un message via MSN à zave
Bonjour RunCodePhp et merci pour ton intervention très intéressante.

Je n'ai nullement envie de me fâcher avec la POO, au contraire c'est un paradigme qui suscite chez moi un intérêt certain. Le modèle objet de PHP 4, ne m'avais pas vraiment donné envie de m'y attarder, mais celui de PHP 5 c'est autre chose.

En écrivant ce topic ma démarche est d'être dans les bonnes pratiques, PHP est un langage qui évolue et je tiens à suivre autant que possible son évolution. Ne pas avoir écris de code pendant plus d'un an a créé pas mal de doute sur ce qu'il est bien de faire ou pas. PDO je ne l'ai pas beaucoup utilisé, du coups je me suis demandé si je faisais bien ou pas.

Sinon pour la solution 3, je la connais, j'ai d'ailleurs ce genre de classe dans mes tiroirs.

Code :
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
<?php
class pdos extends PDO {
 
	private static $_instance;
 
	public function __construct() {
	}
 
	/* Singleton */
	public static function getInstance() {
 
		if (!isset(self::$_instance)) {
 
			try {
 
				self::$_instance = new PDO('mysql:host='.DB_HOST.';dbname='.DB_BDD, DB_USER, DB_PASS);
 
			} catch (PDOException $e) {
 
				echo 'Erreur : '.$e->getMessage().'<br />';
				echo 'N° : '.$e->getCode().'<br />';
			}
		} 
		return self::$_instance; 
	}
 
	public function __clone()
	{
		throw new Exception('Je suis un singleton, ne me clonez pas !');
	} 
}
?>
Maintenant que je sais que la méthode d'avant qui consistait à ouvrir une connexion et la laisser ouverte ne ce fait plus, je n'hésiterai pas à utiliser la solution 3, même dans un projet non-objet.

Merci à tout ceux qui ont pris le temps de me répondre
zave est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2010, 11h49   #7
Modérateur
 
Inscription : septembre 2010
Messages : 6 998
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 6 998
Points : 8 311
Points : 8 311
tu peu regardé aussi du coté de Registry
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h18.


 
 
 
 
Partenaires

Hébergement Web