Services webmasters
Partenaires
Jeux concours gratuits
 
Les fonctions magiques __sleep et __wakeup
<<<
Références dans un constructeur Comparer des objets en PHP 4
>>>

4.9 Les classes et les objets
4 Référence
 Manuel PHP

Les classes : class
extends : héritage
Constructor : constructeur
Opérateur ::
parent
Sauvegarde d'objets - cas des sessions
Les fonctions magiques __sleep et __wakeup
->Références dans un constructeur
Comparer des objets en PHP 4
Comparer des objets en PHP 4

4.9.8 Références dans un constructeur

Créer des références dans un constructeur peut conduire à des résultats étranges. Ce tutoriel vous guide pour éviter ces problèmes.

<?php
class foo {
    function
foo($name) {
        
// crée une référence dans le tableau global $globalref
        
global $globalref;
        
$globalref[] = &$this;
        
// donne le nom de la variable
        
$this->setName($name);
        
// et l'affiche
        
$this->echoName();
    }
    function
echoName() {
        echo
"<br>",$this->Name;
    }
    function
setName($name)    {
        
$this->Name = $name;
    }
}
?>

Vérifions maintenant qu'il y a une différence entre $bar1 qui a été créé avec = et $bar2 qui a été créé avec l'opérateur de référence =& :


<?php
    $bar1
= new foo('crée dans le constructeur');
    
$bar1->echoName();
    
$globalref[0]->echoName();
    
/* affiche :
    crée dans le constructeur
    crée dans le constructeur
    crée dans le constructeur */
    
$bar2 =&new foo('crée dans le constructeur');
    
$bar2->echoName();
    
$globalref[1]->echoName();
    
/* affiche :
    crée dans le constructeur
    crée dans le constructeur
    crée dans le constructeur */
?>

Apparemment, il n'y a pas de différence, mais en fait, il y en a une significative : $bar1 et $globalref[0] ne sont pas référencées, ces deux variables sont différentes. Cela est du au fait que l'opérateur "new"ne retourne par de référence, mais retourne une copie.
Note

Il n'y a aucune perte de performances (puisque PHP 4 utilise un compteur de références) à retourner des copies au lieu de références. Au contraire, il est souvent mieux de travailler sur les copies plutôt que sur les références, car créer une référence prend un peu plus de temps que de créer une copie qui ne prend virtuellement pas de temps (à moins de créer un tableau géant ou un objet monstrueux, auquel cas il est préférable de passer par des références).

Pour prouver ceci, regardez le code suivant :

Références et constructeurs

<?php
        
// maintenant, nous allons changer de nom. Qu'attendez-vous?
        // Vous pouvez vous attendre à ce que les deux variables $bar
        // et  $globalref[0] changent de nom...
        
$bar1->setName('modifié');
        
// comme prédit, ce n'est pas le cas
        
$bar1->echoName();
        
$globalref[0]->echoName();
        
/* affiche :
        crée dans le constructeur
        modifié */
        // quelle est la différence entre $bar2 et $globalref[1]
        
$bar2->setName('modifié');
        
// Heureusement, elles sont non seulement égales, mais
        // elles représentent la même variable.
        // donc $bar2->Name et $globalref[1]->Name sont les mêmes
        
$bar2->echoName();
        
$globalref[1]->echoName();
        
/* affiche :
        modifié
        modifié */
?>

Un dernier exemple pour bien comprendre.

<?php
class a {
    function
a($i) {
        
$this->value = $i;
        
// Essayez de comprendre on n'a pas besoin de
        // référence ici
        
$this->b = new b($this);
    }
    function
createRef() {
        
$this->c = new b($this);
    }
    function
echoValue() {
        echo
"<br>","class ",get_class($this),': ',$this->value;
    }
}
class
b  {
    function
b(&$a) {
        
$this->a = &$a;
    }
   function
echoValue() {
        echo
"<br>","class ",get_class($this),': ',$this->a->value;
        }
}
// Essayez de comprendre pourquoi une copie simple va
// conduire à un résultat indésirable à
// la ligne marquée d'une étoile
$a =&new a(10);
$a->createR color="#0000BB">value = 11;
$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();
/*
output:
class a: 10
class b: 10
class b: 10
class a: 11
class b: 11
class b: 11
*/
?>

<< Références dans un constructeur >>
Les fonctions magiques __sleep et __wakeup Les classes et les objets Comparer des objets en PHP 4
Services webmasters
Les manuels
 
CoursPHP.com - Reproduction interdite -