Aller au menu - Aller au contenu
Inscris-toi au e-camp "Héberge ton jeu Facebook sur Azure" de Microsoft vendredi 25 mai à 13h30 !

Modifier une entrée en POO et PDO

débutant POO

Pour accéder à cette section
Connectez-vous !
connexion_rpx

Offre d'emploi : Développeur Web PHP/Drupal (H/F)

Page 1  2  Suivante
Auteur Message
1 visiteur sur ce sujet (1 Anonyme)
Page 1  2  Suivante
Hors ligne R-transat # Posté le 28/06/2010 à 21:55:35
Avatar

Bonsoir,

Je suis en train d'apprendre la POO avec le tuto de m@téo. Et j'essaye d'implémenter la mise à jour d'un membre et le WHERE de ma requête n'est pas pris en compte, je ne vois pas comment faire...


Et y-a t-il possibilité d'optimiser la connexion à la BDD dans recréer un objet PDO ?

Voila mon code :

Code : PHP
 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
<?php
class Membre 
{
	private $membreid;
	private $pseudo;
	private $email;
	private $signature;
	private $actif;
	
	public function __construct($idMembre){
		$bdd = new PDO('mysql:host=localhost;dbname=poo', 'root', '');
		$sql = "SELECT * FROM membres WHERE id= '".$idMembre."'";
		$req = $bdd->query($sql);
		
		$data = $req->fetch(PDO::FETCH_OBJ);
		$this->membreid = $data->id;
		$this->pseudo = $data->pseudo;
	}
	
	public function getPseudo(){
		return $this->pseudo;
	}
	
	public function setPseudo($nouveauPseudo){
		if(!empty($nouveauPseudo) && strlen($nouveauPseudo) > 5){
			$bdd = new PDO('mysql:host=localhost;dbname=poo', 'root', '');
			$sql = "UPDATE membres SET pseudo = '".$nouveauPseudo."' WHERE id = '".$this->membreid."'";
			$bdd->exec($sql);
			$this->pseudo = $nouveauPseudo;
		}
		
	}	
}

?>


Le code que j'exécute :

Code : PHP
1
2
3
4
5
6
7
<?php
require_once('Membre.class.php');

$membre = new Membre(2);
$membre->setPseudo('pseudo4');
echo $membre->getPseudo() . ', modifié';
?>


Merci d'avance.
Édité le 28/06/2010 à 21:58:31 par R-transat
Publicité # Posté le 28/06/2010 à 21:55:35

Hors ligne RyDroid # Posté le 28/06/2010 à 22:07:13
rayquaza devient RyDroid
Avatar

Ville : Reims
Pays : France métropolitaine

N'utilise pas de majuscules pour des noms de fichiers ^^ .

Pourquoi faire une variable SQL que tu n'utilise qu'une fois ?
Il y ales requêtes préparés pour les variables dans les requêtes ;) .
 
Hors ligne R-transat # Posté le 28/06/2010 à 22:10:13
Avatar

Je ne connais pas grand chose à PDO et POO, j'aimerai savoir comment faire ^^ . Pour ça que je demande comment faire l'update selon l'id
Édité le 28/06/2010 à 22:12:42 par R-transat
Hors ligne RyDroid # Posté le 28/06/2010 à 22:15:48
rayquaza devient RyDroid
Avatar

Ville : Reims
Pays : France métropolitaine

Commence déja par corriger, les 2 erreurs que je t'ai signalé.

Les majuscules risque de ne pas include ton fichier.
Et la requête non préparé risque de te poser des problèmes de sécurité.
 
Hors ligne R-transat # Posté le 29/06/2010 à 19:45:17
Avatar

Ca ne m'aide pas pour inclure une seule fois la connexion à la base de donnée :(
Hors ligne Ge0 # Posté le 22/08/2010 à 00:32:44
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

J'ai du mal à trouver des réponses à quelques interrogations, mais j'ai trouvé ce sujet intéressant et c'est pourquoi je le remonte.

Je voudrais savoir si c'est mal de faire :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?php
class Foo {
	private $instance = null;
	public function __construct() {
		try {
			$this->instance = new PDO('machinchose');
		} catch(Exception $e) {
			// Machin chose
		}
	}
}

$foo1 = new Foo;
$foo2 = new Foo;
?>


Comme on peut le voir, on instancie deux objets qui, eux-mêmes, instancient deux objets PDO. Donc deux connexions ? Je ne sais pas.

Je voulais savoir quelle était la meilleur solution sans avoir à passer une référence sur notre instance de PDO dans notre classe. Et je voudrais aussi savoir si le fait d'instancier une instance PDO au sein d'un objet est à fuir comme la peste.

Merci.
 
Hors ligne sachav # Posté le 22/08/2010 à 00:59:02

Visiblement oui, les connexions à MySQL ne se référencient pas automatiquement.

Un petit test rapide en reprenant ta classe Foo :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
class Foo {
	private $instance = null;
	public function __construct() {
		try {
			$this->instance = new PDO('mysql:host=localhost;dbname=tests', 'root', '');
			debug_zval_dump($this->instance);
		} catch(Exception $e) {
			var_dump($e);
		}
	}
}
$foo1 = new Foo;
$foo2 = new Foo;
$foo3 = new Foo;
$foo4 = new Foo;
?>


Avec ça, on se retrouve toujours avec un refcount de 2 pour Foo::instance. Donc on a plusieurs connexions.

Une seconde preuve :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
class Foo {
	private $instance = null;
	public function __construct() {
		try {
			$this->instance = new PDO('mysql:host=localhost;dbname=tests', 'root', '');
			debug_zval_dump($this->instance);
		} catch(Exception $e) {
			var_dump($e);
		}
	}
}
$foos = array();
while(1) {
	$foos[] = new Foo;
}
?>


Et en faisant un petit tour sur phpMyAdmin pendant que la boucle tourne :

Code : Console
#1040 - Too many connections


Personellement, j'instancierais PDO là où tu fais toutes les instanciations (ce qui permet aussi de garder une organisation au niveau du code, on ne se retrouve pas avec des new PDO au milieu d'une méthode), puis on passe l'instance de PDO pour chaque objet qui en a besoin (via __construct ou autre). C'est la seule solution que je vois à part utiliser un truc horrible genre $GLOBALS.
Édité le 22/08/2010 à 01:00:17 par sachav
Hors ligne Ge0 # Posté le 22/08/2010 à 10:38:24
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

D'accord, merci.

Et pourquoi ça serait "horrible", de passer ça en $GLOBALS ?
 
Hors ligne sachav # Posté le 22/08/2010 à 10:55:32

Par convention je dirais, menfin c'est plutôt parce que je vois ça nul part.

Mais bon, on peut toujours le faire.
Hors ligne Ge0 # Posté le 22/08/2010 à 11:50:25
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

C'est pas faux, mais imagine tu utilises les fonctions type mysql_ voire mysqli_, t'as pas ce souci de passer une instance en argument, etc...

Donc, si pdo est en variable globale, c'est peut-être pas non plus la fin du monde ? :p
 
Hors ligne RPGamer # Posté le 22/08/2010 à 14:58:21
∞! = ∞ * ∞
Avatar

Études : Heig-VD

A mon avis, il vaut mieux se contenter de passer une instance "générale" au constructeur lorsqu'elle est utilisée par plusieurs autres instances.

Pour la question des multiples connexions, c'est dû au fait que l'instance de PDO est un attribut privé de ta classe Foo.
 
Hors ligne Ge0 # Posté le 22/08/2010 à 18:57:39
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

Citation : RPGamer
A mon avis, il vaut mieux se contenter de passer une instance "générale" au constructeur lorsqu'elle est utilisée par plusieurs autres instances.


Une variable statique référençant la poignée PDO ?

Citation : RPGamer
Pour la question des multiples connexions, c'est dû au fait que l'instance de PDO est un attribut privé de ta classe Foo.


C'est sûr. Mais si tu as des solutions, je suis preneur.

Merci. ;)
 
Connecté christouphe # Posté le 23/08/2010 à 09:17:13
Avatar

Études : Université Paul Sabatier Toulouse

Citation : Geo0w
J'ai du mal à trouver des réponses à quelques interrogations, mais j'ai trouvé ce sujet intéressant et c'est pourquoi je le remonte.

Je voudrais savoir si c'est mal de faire :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?php
class Foo {
	private $instance = null;
	public function __construct() {
		try {
			$this->instance = new PDO('machinchose');
		} catch(Exception $e) {
			// Machin chose
		}
	}
}

$foo1 = new Foo;
$foo2 = new Foo;
?>


Comme on peut le voir, on instancie deux objets qui, eux-mêmes, instancient deux objets PDO. Donc deux connexions ? Je ne sais pas.

Je voulais savoir quelle était la meilleur solution sans avoir à passer une référence sur notre instance de PDO dans notre classe. Et je voudrais aussi savoir si le fait d'instancier une instance PDO au sein d'un objet est à fuir comme la peste.

Merci.


Je te cite à ce niveau, car c'est là que c'est le plus intéressant:

Citation : Geo0w

Comme on peut le voir, on instancie deux objets qui, eux-mêmes, instancient deux objets PDO. Donc deux connexions ? Je ne sais pas.


Quel intérêt d'avoir deux connexion identiques ? Une seule suffit, il suffit de l'instancier là où il faut.

Citation : Geo0w

Je voulais savoir quelle était la meilleur solution sans avoir à passer une référence sur notre instance de PDO dans notre classe. Et je voudrais aussi savoir si le fait d'instancier une instance PDO au sein d'un objet est à fuir comme la peste.


J'y viens de suite:

Dans une application web, et par page, tu n'a besoin que d'UNE SEULE connexion référençant UNE base de donnée (donc oui, tu peux avoir plusieurs connexion mai sur des bdd différentes, MAIS là encore une seule suffit, car dès que tu es connecté au moteur SGBD, tu peu préfixer les table avec le nom de la bdd pour y accéder:

Code : SQL
1
select t1.toto,t2.tata from bdd1.t1 t1,bdd2.t2 t2 WHERE condition


En plus, niveau objet, et même en procédural, il faudrait apprendre à proscrire le plus possible les variables globales. Instancie ton objet connexion à un niveau supérieur et passe le dans le constructeur de tes objets:

index.php
Code : PHP
1
2
3
4
5
6
7
8
9
<?php
    //du code, session_start()...etc
    $oPdo = new PDO("blablabla");

    //du code + include des script de tes classes...
    include_once("classes/monObjet.class.php");
    $oMonObjet = new monObjet($oPdo,"tata",3);

?>


Classe monObjet
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
class monObjet {

    private $_oConnexion = null; // _ == convention pour privé ;-)
    private $_tata;
    private $_unNombre;

    public function __construct(PDO $oConnexion,$nom,$nombre) {
        $this -> _oConnexion = $oConnexion;
        $this -> _tata= $nom;
        $this -> _unNombre= $nombre;
    }
}
?>


Dans cet exeple, le constructeur prend en premier paramètre, un objet PDO étant la connexion à la BDD. Plus besoin de faire la connexion DANS la classe instanciée.

Une fois que vous éliminez l'impossible, peu importe si ce qui reste est improbable, ce devrait être la vérité. :p
"Tracker addict ;) :-° ", La POO en PHP, il n'y a que ça de vrai :D
La solution à vos problèmes en PHP - Un objet peut-il être en session ? - Comment utiliser correctement les dates dans un programme ? - /!\ A LIRE SI VOUS UTILISEZ PDO /!\
 
Hors ligne Ge0 # Posté le 23/08/2010 à 11:37:27
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

Salut, christouphe.

Tout d'abord, je tiens à te remercier quant à la pertinence et la clarté de ton message.

Citation : christouphe
Quel intérêt d'avoir deux connexion identiques ?


Là n'était pas le but, justement. Mon but est bel et bien de garder une et une seule connexion. Seulement, je n'étais pas sûr du fait que si j'instanciais n objets PDO, alors j'aurais n connexions. Mais maintenant, je suis fixé.

Ensuite, comme je l'ai dit, ça risque d'être barbant, à force de passer une instance PDO au constructeur. Mais puisque cela semble la meilleure solution, autant s'y faire.

Pour le "_" par convention, je le mettais bien que je n'en étais pas totalement sûr. Merci pour la confirmation, c'est top. ;)

Ensuite, j'ai pas les moyens de vérifier, là, maintenant, mais :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
class monObjet {

    private $_oConnexion = null; // _ == convention pour privé ;-)
    private $_tata;
    private $_unNombre;

    public function __construct(PDO $oConnexion,$nom,$nombre) {
        $this -> _oConnexion = $oConnexion;
        $this -> _tata= $nom;
        $this -> _unNombre= $nombre;
    }
}
?>


Plus particulièrement la ligne :
Code : PHP
1
2
3
<?php
$this -> _oConnexion = $oConnexion;
?>


N'y a-t-il pas une copie de l'objet, donc une "reconstruction" et ainsi une nouvelle connexion enclenchée par PDO ? Ne faut-il pas plutôt faire :

Code : PHP
1
2
3
<?php
$this -> _oConnexion = &$oConnexion;
?>


Merci encore ! :)
 
Connecté christouphe # Posté le 23/08/2010 à 11:45:05
Avatar

Études : Université Paul Sabatier Toulouse

OUUUUH la bonne question qu'elle est bonne ;)

Je teste ça de suite avec mon IDE favori et je te dis :p

EDIT:
ça donnerait la même chose:

Le code:
Code : PHP
 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
<?php
class monObjet {

    private $_oConnexion = null; // _ == convention pour privé ;-)
    private $_tata;
    private $_unNombre;

    public function __construct(PDO &$oConnexion,$nom,$nombre) {
        $this -> _oConnexion = $oConnexion;
        $this -> _tata= $nom;
        $this -> _unNombre= $nombre;
    }
}

    //du code, session_start()...etc
    try {
        $oPdo = new PDO('mysql:dbname=monjeu;host=localhost','root','root');
    } catch (Exception $e) {
        echo $e->getMessage();
    }

    echo '<pre>'.print_r($oPdo,true).'</pre>';
    //du code + include des script de tes classes...

    $oMonObjet = new monObjet($oPdo,"tata",3);
    echo '<pre>'.print_r($oMonObjet,true).'</pre>';
?>


Le résultat:
Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
PDO Object
(
)

monObjet Object
(
    [_oConnexion:monObjet:private] => PDO Object
        (
        )

    [_tata:monObjet:private] => tata
    [_unNombre:monObjet:private] => 3
)


Pareil avec PDO $oConnexion au lieu de &$oConnexion dans la déclaration du constructeur.
Édité le 23/08/2010 à 11:54:42 par christouphe

Une fois que vous éliminez l'impossible, peu importe si ce qui reste est improbable, ce devrait être la vérité. :p
"Tracker addict ;) :-° ", La POO en PHP, il n'y a que ça de vrai :D
La solution à vos problèmes en PHP - Un objet peut-il être en session ? - Comment utiliser correctement les dates dans un programme ? - /!\ A LIRE SI VOUS UTILISEZ PDO /!\
 
Hors ligne Ge0 # Posté le 23/08/2010 à 13:08:07
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

Ton IDE favoris ? Lequel ? :)

Merci infiniment, je suis fixé. Faut passer une instance en argument ou, si on n'a pas peur de l'horrible :

Code : PHP
1
2
3
4
5
6
<?php
try {
        $GLOBALS['oPdo'] = new PDO('mysql:dbname=monjeu;host=localhost','root','root');
    } catch (Exception $e) {
        echo $e->getMessage();
    }

 
Connecté christouphe # Posté le 23/08/2010 à 13:09:33
Avatar

Études : Université Paul Sabatier Toulouse

NetBeans, sinon l'horrible Global "vade retro"...il faut que je fade tous les script en tcl au taff pour les dégager...et j'en ai un wagon :p

Une fois que vous éliminez l'impossible, peu importe si ce qui reste est improbable, ce devrait être la vérité. :p
"Tracker addict ;) :-° ", La POO en PHP, il n'y a que ça de vrai :D
La solution à vos problèmes en PHP - Un objet peut-il être en session ? - Comment utiliser correctement les dates dans un programme ? - /!\ A LIRE SI VOUS UTILISEZ PDO /!\
 
Hors ligne Ge0 # Posté le 23/08/2010 à 13:12:29
bidouille !
Avatar
Groupe : Anciens
Flux RSS

Ville : Lyon
Pays : France métropolitaine
Études : ITII Lyon

NetBeans, oui, j'en avais entendu parler.

J'ai pas bougé de Notepad++ depuis que je connais ce site... Il serait peut-être temps de changer un peu.

Merci encore. Mon Dieu, que de reconnaissance pour toi, christouphe. :D
 
Connecté christouphe # Posté le 23/08/2010 à 13:16:34
Avatar

Études : Université Paul Sabatier Toulouse

L'avantage que j'ai trouvé à NetBeans, c'est la complétion de code et la rapidité de développement par rapport à d'autres éditeurs.

Une fois que vous éliminez l'impossible, peu importe si ce qui reste est improbable, ce devrait être la vérité. :p
"Tracker addict ;) :-° ", La POO en PHP, il n'y a que ça de vrai :D
La solution à vos problèmes en PHP - Un objet peut-il être en session ? - Comment utiliser correctement les dates dans un programme ? - /!\ A LIRE SI VOUS UTILISEZ PDO /!\
 
Hors ligne Albeneth # Posté le 23/08/2010 à 17:33:19
Avatar

Ville : Pessac
Pays : France métropolitaine
Études : Epitech Bordeaux

Je plussoie pour NetBeans, qui est un excellent éditeur :)

J'aimerais revenir sur ton "excellente question". Une variable où l'on instancie un nouvel objet ne contient pas l'objet en question, mais un identifiant pour le retrouver. Ainsi, toutes les modifications apportées à une variable où l'objet a été "copié" seront faites sur toutes les variables contenant l'id de l'objet. (source)
Hors ligne gyom # Posté le 23/08/2010 à 19:22:21
« Pain is scary. »
Avatar

Études : Université de Lyon

Bonjour :)

Personnellement je préfère Eclipse que NetBeans. :D

Sinon, concernant le problème de R-transat, je ne suis pas d'avis que la classe membre doivent s'occuper de la connexion avec le SGBD. Pour moi, cet objet a pour fonction de "représenter" un membre. Point. Le travaille de relation avec la BDD doit être effectué par un autre objet, qui serait charger de gérer les changements en BDD qui concernent le membre (un "gestionnaire" de membres quelques sortes). Du coup, il serait le seul à avoir besoin d'une instance de PDO en attribut.

Sinon oui, dans le cas où un script utilise plusieurs objets qui ont une instance de PDO en attribut, il faut s'assurer qu'ils partagent la même pour ne pas dupliquer les ressources.

@christouphe : Il y a un truc que je trouve pas logique dans le code d'exemple que tu as donné. Je le mets pour rappel (en mode secret), et je mets ensuite ce que j'aurais fait moi :
Secret (cliquez pour afficher)
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
class monObjet {

    private $_oConnexion = null; // _ == convention pour privé ;-)
    private $_tata;
    private $_unNombre;

    public function __construct(PDO &$oConnexion,$nom,$nombre) {
        $this -> _oConnexion = $oConnexion;
        $this -> _tata= $nom;
        $this -> _unNombre= $nombre;
    }
}

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
class monObjet {

    private $_oConnexion = null; // _ == convention pour privé ;-)
    private $_tata;
    private $_unNombre;

    public function __construct(PDO $oConnexion,$nom,$nombre) {
        $this -> _oConnexion = & $oConnexion;
        $this -> _tata= $nom;
        $this -> _unNombre= $nombre;
    }
}


Ainsi on stock une référence de l'objet dans l'attribut, non ? Alors que ton code stock une copie de la référence d'un objet (si j'ai bien suivi).

Hé oui, c'est tordu les références, j'ai peut être dit de la merde mais j'ai bien du mal avec ces saletés.

Si tu donnes une solution toute prête alors que je suis en train de tenter d'aider l'OP à trouver par lui-même, je te bouffe.
PDO : comprendre et corriger les erreurs les plus fréquentes
MySQLWrapper - un wrapper pour l'API MySQL, utile si vous ne disposez ni de PDO, ni de MySQLi (page persos free…)
 
Hors ligne Mat 3910 # Posté le 23/08/2010 à 19:30:31
Moi ? Jm'en fou...
Avatar

Depuis PHP5, je crois bien que les objets sont passé automatiquement en référence.

EDIT : Je viens de regarder dans la "bible", effectivement ce que je dis est vrai.
"PHP 5 avancé, 5ème édition" p. 273
Édité le 23/08/2010 à 19:42:50 par Mat 3910
Hors ligne gyom # Posté le 23/08/2010 à 19:33:08
« Pain is scary. »
Avatar

Études : Université de Lyon

C'est ce que je croyais aussi, mais apparemment il reste encore une ou deux subtilités ... qui m'échappent totalement ! Je relirai l'article donné par Albeneth tout à l'heure.

Edit pour au dessus : Oui, mais regarde ce qui est dit sur PHP.net :
Citation : PHP.net
Un des piliers de la POO de PHP 5 est le fait que les "objets sont passés par référence par défaut". Ce n'est pas complètement vrai. Cette section rectifie cette généralisation avec quelques exemples.


Ce que je ne comprends pas, c'est la différence entre ces deux commentaires (code d'exemple dans l'article) :
Code : PHP
1
2
3
4
<?php
$a = new A;
$b = $a;     // $a et $b sont des copies du même identifiant
             // ($a) = ($b) = <id>


Code : PHP
1
2
3
<?php$c = new A;
$d = &$c;    // $c et $d sont des références
             // ($c,$d) = <id>
Édité le 23/08/2010 à 19:52:51 par gyom

Si tu donnes une solution toute prête alors que je suis en train de tenter d'aider l'OP à trouver par lui-même, je te bouffe.
PDO : comprendre et corriger les erreurs les plus fréquentes
MySQLWrapper - un wrapper pour l'API MySQL, utile si vous ne disposez ni de PDO, ni de MySQLi (page persos free…)
 
Hors ligne Mat 3910 # Posté le 23/08/2010 à 19:51:01
Moi ? Jm'en fou...
Avatar

Dans ce cas là ça marchera. Il est similaire au troisième exemple de l'article donné par Albeneth.
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
$e = new A;

function foo($obj) {
    // ($obj) = ($e) = <id>
    $obj->foo = 2;
}

foo($e);
echo $e->foo."\n";
//affiche 2
?>

L'objet est bien passé en référence à la fonction vu qu'il affiche 2 et non 1.

Du coup, vous savez comment passer un objet directement par copie ?
Est ce que la syntaxe <?php foo(clone $e); ?> marche ?

EDIT suite à l'EDIT de gyom :o : Si j'ai bien compris $a et une référence de l'objet A, et $b est une copie de cette référence. Alors que $c est une référence à l'objet A, et $d est une référence à $c.
Édité le 23/08/2010 à 19:58:26 par Mat 3910
Hors ligne gyom # Posté le 23/08/2010 à 20:05:43
« Pain is scary. »
Avatar

Études : Université de Lyon

Je ne sais pas, je ne comprends rien pour être honnête. J'ai testé ce code :
Code : PHP
 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
<?php
class Foo
{
	public $attr = '';
}

$a = new Foo();
$a->attr = 'a';
$b = $a;
$b->attr = 'b';

function bar(Foo $param)
{
	$res = &$param;
	$res->attr = 'param';
	return $res;
}

$c = bar($b);

var_dump($a);
echo '<br />';
var_dump($b);
echo '<br />';
var_dump($c);


Et j'obtiens cela :
Code : Console
object(Foo)#1 (1) { ["attr"]=> string(5) "param" } 
object(Foo)#1 (1) { ["attr"]=> string(5) "param" } 
object(Foo)#1 (1) { ["attr"]=> string(5) "param" }


Du coup je ne comprends pas pourquoi la doc dit que ce n'est "pas complètement vrai" ...

Si tu donnes une solution toute prête alors que je suis en train de tenter d'aider l'OP à trouver par lui-même, je te bouffe.
PDO : comprendre et corriger les erreurs les plus fréquentes
MySQLWrapper - un wrapper pour l'API MySQL, utile si vous ne disposez ni de PDO, ni de MySQLi (page persos free…)
 
Hors ligne mwsaz # Posté le 23/08/2010 à 20:06:10
Avatar
Flux RSS

Bonsoir,

Pour ce qui est de partager une ressource dans plusieurs contextes, la meilleure solution reste le pattern Singleton. En général, on l'implémente dans une classe (l'instance est stockée en variable de classe et une fonction permet de la récupérer). Sous la forme d'une fonction, ça donne ça :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
function getDbHandle()
{
  static $handle = null;
  if ($handle === null)
  {
    // Instancier l'objet et le stocker dans $handle
    $handle = new PDO(...
  }
  return $handle;
}

L'avantage de ce système est qu'on ne peut pas écraser malencontreusement la classe (ou la fonction dans l'exemple), contrairement à une variable globale.

Sous forme de classe (la plus répandue) :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
class Bdd extends PDO
{
  public function getHandle()
    static $handle = null;
    if ($handle === null)
    {
      // Instancier l'objet et le stocker dans $handle
      $handle = new PDO(...
    }
    return $handle;
}

// Que l'on utilise comme ça (n'importe où dans le code) :

$db = Bdd::getHandle();
$db->prepare(... // S'utilise comme une instance PDO classique


Concernant les objets, leurs instances sont juste des identifiants (considérez-les comme des références, c'est presque pareil).

Code : PHP
1
2
3
<?php
$A = new Foo();
$B = $A; // $A et $B "pointent" vers la même instance

Si l'on veut une copie de l'objet, il faut utiliser le mot-clé clone :
Code : PHP
1
2
3
<?php
$A = new Foo();
$B = clone $A; // $A et $B sont deux instances distinctes


Faire $A = &$B n'a pas de sens (enfin si, mais c'est inutile) dès lors que $A contient une instance (un identifiant d'une instance). Vous pouvez les voir comme les pointeurs en C, en quelque sorte.

Attention, pour les classes qui ne contiennent pas uniquement des attributs scalaires (réels, chaînes de caractères, array des deux éléments précédents), il faudra écrire un constructeur dit de copie qui se chargera de créer de nouvelles instances des classes / ressources contenues.

En espérant avoir clarifié quelques points. :)
Édité le 23/08/2010 à 20:08:49 par mwsaz

Image utilisateurImage utilisateur

Objets innanimés, avez-vous donc une âme?
Qui s'attache à notre âme et nous force à l'aimer.
 
Hors ligne gyom # Posté le 23/08/2010 à 20:09:29
« Pain is scary. »
Avatar

Études : Université de Lyon

Merci pour ces précisions mwsaz, cependant ça ne calme pas ma curiosité, car ce qui reste mystérieux est contenu dans cette phrase que tu viens d'écrire :
Citation : mwsaz
Faire $A = &$B n'a pas de sens (enfin si, mais c'est inutile) dès lors que $A contient une instance (un identifiant d'une instance).


Alors le & ne fait plus rien depuis PHP4 ? Ou alors il fait encore une petite subtilité (comme semble le suggérer la doc) ? Si oui, quelle est cette subtilité ?
Édité le 23/08/2010 à 20:09:46 par gyom

Si tu donnes une solution toute prête alors que je suis en train de tenter d'aider l'OP à trouver par lui-même, je te bouffe.
PDO : comprendre et corriger les erreurs les plus fréquentes
MySQLWrapper - un wrapper pour l'API MySQL, utile si vous ne disposez ni de PDO, ni de MySQLi (page persos free…)
 
Hors ligne mwsaz # Posté le 23/08/2010 à 20:12:03
Avatar
Flux RSS

Ma remarque n'est valable que pour les instances de classes.

Tu peux considérer que quoi que tu fasses, un object est toujours passé par référence.

Par contre, l'usage du & reste utile pour les scalaires :
Code : PHP
1
2
3
4
5
6
<?php
$a = 10;
$b = &$a;

$b++;
// $a contient 11


EDIT : Corrigé le 10 + 1 = 9 :-°
Édité le 23/08/2010 à 20:13:09 par mwsaz

Image utilisateurImage utilisateur

Objets innanimés, avez-vous donc une âme?
Qui s'attache à notre âme et nous force à l'aimer.
 
Connecté Morgin # Posté le 23/08/2010 à 20:13:24
Le jeu, c'est la vie !
Avatar

Ville : Limoges
Pays : France métropolitaine
Études : Lycée Michel Montaigne - Bordeaux

Et bien pour l'avoir utilisé il y a peu, sous PHP5, & permet de "lier" je ne sais pas si c'est le bon terme.
Enfin de donner un autre nom au même ensemble de données, je me trompe ?

EDIT : $a contient 11, non ?
 
Hors ligne mwsaz # Posté le 23/08/2010 à 20:15:33
Avatar
Flux RSS

Le terme exact est une référence. Donc oui, $a et $b sont "synonymes".

Image utilisateurImage utilisateur

Objets innanimés, avez-vous donc une âme?
Qui s'attache à notre âme et nous force à l'aimer.
 

Retour au forum "PHP" ou à la liste des forums

Pour accéder à cette section
Connectez-vous !
connexion_rpx