Wygląda na to, że w PHP obiekty są przekazywane przez referencje. Wydaje się, że nawet operatory przypisania nie tworzą kopii obiektu.
Oto prosty, wymyślony dowód:
<?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'
?>
W obu przypadkach drukowania otrzymuję „po”
Jak więc przekazać $ a do set_b () przez wartość, a nie przez odniesienie?
php
copy
clone
shallow-copy
Nick Stinemate
źródło
źródło
(object) ((array) $objectA)
może dać takie same pożądane rezultaty z lepszą wydajnością niż użycieclone $objectA
lubnew stdClass
.Odpowiedzi:
W PHP 5+ obiekty są przekazywane przez referencje. W PHP 4 są one przekazywane przez wartość (z tego powodu w czasie wykonywania zostało przekazane przez odwołanie, które stało się przestarzałe).
Możesz użyć operatora „clone” w PHP5 do kopiowania obiektów:
Poza tym to tylko obiekty przekazywane przez odniesienie, a nie wszystko, co powiedziałeś w swoim pytaniu ...
źródło
$a = new stdClass; $b =& $a; $a = 42; var_export($b);
tutaj$b
jest odniesienie do zmiennej$a
; jeśli zastąpi=&
się normalne=
, to nie odwołanie, i nadal zwraca się do oryginalnego obiektu.Odpowiedzi można często znaleźć w książkach Java.
cloning: Jeśli nie zastąpisz metody clone, domyślnym zachowaniem jest płytka kopia. Jeśli twoje obiekty mają tylko prymitywne zmienne składowe, wszystko jest w porządku. Ale w języku bez typu, w którym inny obiekt jest zmiennymi składowymi, jest to ból głowy.
serializacja / deserializacja
$new_object = unserialize(serialize($your_object))
Zapewnia to głębokie kopiowanie przy dużym koszcie w zależności od złożoności obiektu.
źródło
$a = clone $b
bez użycia magicznych__clone()
metod) jest równoważna spojrzeniu na każdą z właściwości obiektu$b
w terminach i przypisaniu do tej samej właściwości w nowym elemencie tej samej klasy przy użyciu=
. Właściwości, które są obiektami, nie otrzymająclone
d, podobnie jak obiekty wewnątrz tablicy; to samo dotyczy zmiennych związanych przez odniesienie; wszystko inne jest tylko wartością i jest kopiowane tak jak w przypadku każdego zadania.Call to method __clone from invalid context
:)$new_date = (clone $date_start)->subDays(1);
Nie udaje się to()
, jeśli je usunę, pojawia się inny błąd. Chodzi o to, że używamy dokładnie tego samego php 7.2.3, a mój działa dobrze. Jakieś pomysły? Wszędzie wyszukiwane ..Zgodnie z poprzednim komentarzem, jeśli masz inny obiekt jako zmienną składową, wykonaj następujące czynności:
Teraz możesz klonować:
źródło
Zgodnie z dokumentacją ( http://ca3.php.net/language.oop5.cloning ):
źródło
Aby wyjaśnić, że PHP używa kopiowania przy zapisie, więc w zasadzie wszystko jest odniesieniem, dopóki go nie zmodyfikujesz, ale w przypadku obiektów musisz użyć clone i magicznej metody __clone (), jak w zaakceptowanej odpowiedzi.
źródło
Ten kod pomaga w klonowaniu metod
źródło
Robiłem testy i otrzymałem to:
źródło
W tym przykładzie utworzymy klasę iPhone'a i zrobimy z niej dokładną kopię przez klonowanie
źródło
Jeśli chcesz w pełni skopiować właściwości obiektu w innej instancji, możesz użyć tej techniki:
Serializuj go do JSON, a następnie deserializuj z powrotem do Object.
źródło