Il semble que, dans 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 $ a àset_b ()par valeur, pas par référence?
Dans PHP 5+ objets sont passés par référence. Dans PHP 4, ils sont passés par valeur (c’est pourquoi le temps d’exécution passait par référence, ce qui est devenu obsolète).
Vous pouvez utiliser l'opérateur 'clone' en PHP5 pour copier des objets:
$objectB = clone $objectA;
De plus, ce ne sont que des objets qui sont passés par référence, pas tout ce que vous avez dit dans votre question ...
Les réponses se trouvent généralement dans Java livres.
clonage: si vous ne remplacez pas la méthode de clonage, 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 non typé avec un autre objet comme variable membre, c'est un casse-tête.
sérialisation/désérialisation
$new_object = unserialize(serialize($your_object))
Cela permet une copie en profondeur 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;
}
}
Maintenant, vous pouvez faire du clonage:
$bar = new MyClass();
$foo = clone $bar;
Selon les docs ( http://ca3.php.net/language.oop5.cloning ):
$a = clone $b;
Juste pour clarifier PHP utilise copy en écriture, donc, fondamentalement, tout est une référence jusqu'à ce que vous la 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 iPhone class et en faire une copie exacte par cloning
class iPhone {
public $name;
public $email;
public function __construct($n, $e) {
$this->name = $n;
$this->email = $e;
}
}
$main = new iPhone('Dark', '[email protected]');
$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>";