Question

Il semble qu'en PHP, les objets soient passés par référence. Même les opérateurs d’affectation ne semblent pas créer de copie de l’objet.

Voici une preuve simple et artificielle:

<?php

class A {
    public $b;
}


function set_b($obj) { $obj->b = "after"; }

$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.

set_b($a);

print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'

?>

Dans les deux cas d'impression, je reçois "après"

Alors, comment puis-je passer de $ a à set_b () par valeur, et non par référence?

Était-ce utile?

La solution

En PHP 5+, les objets sont passés par référence. En PHP 4, ils sont passés par valeur (c’est pourquoi le runtime passait par référence, ce qui est devenu obsolète).

Vous pouvez utiliser l'opérateur 'clone' de PHP5 pour copier des objets:

$objectB = clone $objectA;

De plus, il ne s'agit que des objets passés par référence, mais pas tout ce que vous avez dit dans votre question ...

Autres conseils

Les réponses se trouvent couramment dans les livres Java.

  1. clonage: Si vous ne substituez pas la méthode clone, le comportement par défaut est une copie superficielle. Si vos objets ne contiennent que des variables membres primitives, tout va bien. Mais dans un langage sans type avec un autre objet comme variable membre, c'est un casse-tête.

  2. sérialisation / désérialisation

$ new_object = unserialize (sérialiser ($ votre_objet))

Ceci permet une copie profonde avec un coût élevé en fonction de la complexité de l'objet.

Selon le commentaire précédent, si vous avez un autre objet en tant que variable membre, procédez comme suit:

class MyClass {
  private $someObject;

  public function __construct() {
    $this->someObject = new SomeClass();
  }

  public function __clone() {
    $this->someObject = clone $this->someObject;
  }

}

Vous pouvez maintenant faire du clonage:

$bar = new MyClass();
$foo = clone $bar;

Selon les documents ( http://ca3.php.net/language.oop5. clonage ):

$a = clone $b;

Juste pour clarifier, PHP utilise copy en écriture. Donc, fondamentalement, tout est une référence jusqu'à ce que vous le modifiiez, mais pour les objets, vous devez utiliser clone et la méthode magique __clone () comme dans la réponse acceptée.

Ce code aide les méthodes de clonage

class Foo{

    private $run=10;
    public $foo=array(2,array(2,8));
    public function hoo(){return 5;}


    public function __clone(){

        $this->boo=function(){$this->hoo();};

    }
}
$obj=new Foo;

$news=  clone $obj;
var_dump($news->hoo());

Je faisais quelques essais et j'ai eu ceci:     

class A {
  public $property;
}

function set_property($obj) {
  $obj->property = "after";
  var_dump($obj);
}

$a = new A();
$a->property = "before";

// Creates a new Object from $a. Like "new A();"
$b = new $a;
// Makes a Copy of var $a, not referenced.
$c = clone $a;

set_property($a);
// object(A)#1 (1) { ["property"]=> string(5) "after" }

var_dump($a); // Because function set_property get by reference
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($b);
// object(A)#2 (1) { ["property"]=> NULL }
var_dump($c);
// object(A)#3 (1) { ["property"]=> string(6) "before" }

// Now creates a new obj A and passes to the function by clone (will copied)
$d = new A();
$d->property = "before";

set_property(clone $d); // A new variable was created from $d, and not made a reference
// object(A)#5 (1) { ["property"]=> string(5) "after" }

var_dump($d);
// object(A)#4 (1) { ["property"]=> string(6) "before" }

?>

Dans cet exemple, nous allons créer la classe iPhone et en faire une copie exacte par clonage

.
class iPhone {

public $name;
public $email;

    public function __construct($n, $e) {

       $this->name = $n;
       $this->email = $e;

    }
}


$main = new iPhone('Dark', 'm@m.com');
$copy = clone $main;


// if you want to print both objects, just write this    

echo "<pre>"; print_r($main);  echo "</pre>";
echo "<pre>"; print_r($copy);  echo "</pre>";

Si vous souhaitez copier intégralement les propriétés d'un objet dans une autre instance, vous pouvez utiliser cette technique:

Sérialisez-le en JSON, puis déssérialisez-le en objet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top