2010-02-12 14 views
1

J'ai un code qui semble se comporter différemment entre PHP 4 et PHP     5. Ce code ci-dessous:Pourquoi l'opérateur d'affectation PHP agit-il comme une affectation par référence dans ce cas?

class CFoo 
{ 
    var $arr; 

    function CFoo() 
    { 
     $this->arr = array(); 
    } 

    function AddToArray($i) 
    { 
     $this->arr[] = $i; 
    } 

    function DoStuffOnFoo() 
    { 
     for ($i = 0; $i < 10; ++$i) 
     { 
      $foo2 = new CFoo(); 
      $foo2 = $this;   // I expect this to copy, therefore 
            // resetting back to the original $this 
      $foo2->AddToArray($i); 
      echo "Foo2:\n"; 
      print_r($foo2); 
      echo "This:\n"; 
      print_r($this); 
     } 
    } 
} 

$foo1 = new CFoo(); 
$foo1->DoStuffOnFoo(); 

Auparavant, en PHP 4  , l'affectation de foo2 $ serait au-dessus de remettre foo2 $ Retour à la la valeur que $ a été définie à l'origine. Dans ce cas, je m'attendrais à ce qu'il soit défini sur CFoo avec un membre $ arr vide. Cependant, l'affectation de $ foo2 à $ this agit comme une affectation par référence. Foo2 agit comme un alias à cela. Par conséquent, lorsque j'appelle "AddToArray" sur foo2, $ $ arr est également ajouté. Donc, quand je vais ré-assigner foo2 à cela, au lieu d'obtenir la valeur initiale de ceci, je reçois essentiellement une auto affectation.

Est-ce que ce comportement a changé dans PHP   5? Que puis-je faire pour forcer foo2 à en faire une copie?

Répondre

3

La partie orientée objet de PHP a été énormément overhauled in PHP 5. Les objets sont maintenant passés (not exactly but almost) comme références. Voir http://docs.php.net/clone.

Exemple:

$x1 = new StdClass; 
$x1->a = 'x1a'; 

$x2 = $x1; 
$y = clone $x1; 

// Performing operations on x2 affects x1/same underlying object 
$x2->a = 'x2A'; 
$x2->b = 'x2B'; 

// y is a clone/changes do not affect x1 
$y->b = 'yB'; 

echo 'x1: '; print_r($x1); 
echo 'y:'; print_r($y); 

impressions

x1: stdClass Object 
(
    [a] => x2A 
    [b] => x2B 
) 
y:stdClass Object 
(
    [a] => x1a 
    [b] => yB 
) 
3

En PHP 4, une copie a été faite d'un objet sans que vous l'ayez assigné par référence (en utilisant & =). En PHP 5, une référence à l'objet est assignée.

Ainsi, après l'attribution $this-$foo2, $foo2 points $this et non à une nouvelle copie de CFoo.

Pour faire une copie en PHP 5, vous dites clone $this.

Dans les deux cas, l'instruction new précédente est gaspillée.

+1

Comment forcer une copie? –

+0

Juste ajouté la réponse. – Matijs

1

PHP a utilisé des références depuis la version 5. Pour copier des objets, utilisez:

$copy = clone $object; 
2

Oui, PHP 5 est la copie maintenant par référence . Maintenant vous devez clone l'objet pour en faire une copie.