Il semble qu'en PHP les objets sont passés par référence. Même les opérateurs d'affectation ne semblent pas créer une 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 passer $ a à set_b () par valeur, pas par référence?
php
copy
clone
shallow-copy
Nick Stinemates
la source
la source
(object) ((array) $objectA)
peut entraîner les mêmes résultats souhaités avec de meilleures performances que l'utilisation declone $objectA
ounew stdClass
.Réponses:
En PHP 5+, les objets sont passés par référence. En PHP 4, ils sont passés par valeur (c'est pourquoi il avait un passage par référence à l'exécution, qui est devenu obsolète).
Vous pouvez utiliser l'opérateur 'clone' en PHP5 pour copier des objets:
De plus, ce ne sont que des objets qui sont passés par référence, pas tout comme vous l'avez dit dans votre question ...
la source
$a = new stdClass; $b =& $a; $a = 42; var_export($b);
voici$b
une référence à la variable$a
; si vous remplacez=&
par une normale=
, ce n'est pas une référence et pointe toujours vers l'objet d'origine.Les réponses se trouvent généralement dans les livres Java.
clonage: si vous ne remplacez pas la méthode de clonage, le comportement par défaut est une copie superficielle. Si vos objets n'ont que des variables membres primitives, c'est tout à fait correct. Mais dans un langage sans type avec un autre objet comme variables membres, c'est un casse-tête.
sérialisation / désérialisation
$new_object = unserialize(serialize($your_object))
Cela permet d'obtenir une copie profonde avec un coût élevé en fonction de la complexité de l'objet.
la source
$a = clone $b
, sans__clone()
méthodes magiques en jeu) équivaut à regarder chacune des propriétés de l'objet$b
en terme, et à affecter la même propriété dans un nouveau membre de la même classe, en utilisant=
. Les propriétés qui sont des objets n'obtiendront pasclone
d, pas plus que les objets à l'intérieur d'un tableau; il en va de même pour les variables liées par référence; tout le reste n'est qu'une valeur et est copié comme avec n'importe quelle affectation.Call to method __clone from invalid context
:)__clone
correctement votre méthode, comme suggéré par stackoverflow.com/a/186191/1614903 ci-dessous. Voir phpinternalsbook.com/php5/zvals/memory_management.html pour une explication approfondieSelon le commentaire précédent, si vous avez un autre objet comme variable membre, procédez comme suit:
Vous pouvez maintenant faire du clonage:
la source
Selon la documentation ( http://ca3.php.net/language.oop5.cloning ):
la source
Juste pour clarifier, PHP utilise la copie à l'é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.
la source
Ce code aide les méthodes de clonage
la source
Je faisais des tests et j'ai obtenu ceci:
la source
Dans cet exemple, nous allons créer une classe iPhone et en faire une copie exacte par clonage
la source
Si vous souhaitez copier entièrement les propriétés d'un objet dans une autre instance, vous pouvez utiliser cette technique:
Sérialisez-le en JSON, puis dé-sérialisez-le en Object.
la source