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 5
 
  | 
 
  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->createRef(); $a->echoValue(); $a->b->echoValue(); $a->c->echoValue(); $a->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 */ ?>
 
 |   
 |