Tampaknya objek PHP dilewatkan oleh referensi. Bahkan operator penugasan tampaknya tidak membuat salinan Obyek.
Berikut ini adalah bukti sederhana yang dibuat-buat:
<?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'
?>
Dalam kedua kasus cetak saya mendapatkan 'setelah'
Jadi, bagaimana saya meneruskan $ a ke set_b () berdasarkan nilai, bukan dengan referensi?
php
copy
clone
shallow-copy
Nick Stinemates
sumber
sumber
(object) ((array) $objectA)
mungkin menghasilkan hasil yang Anda inginkan sama dengan kinerja yang lebih baik daripada menggunakanclone $objectA
ataunew stdClass
.Jawaban:
Dalam PHP 5+ objek dilewatkan dengan referensi. Dalam PHP 4 mereka dilewatkan oleh nilai (itu sebabnya runtime lulus dengan referensi, yang menjadi usang).
Anda dapat menggunakan operator 'klon' di PHP5 untuk menyalin objek:
Juga, itu hanya objek yang dilewatkan dengan referensi, bukan segalanya seperti yang Anda katakan dalam pertanyaan Anda ...
sumber
$a = new stdClass; $b =& $a; $a = 42; var_export($b);
di sini$b
adalah referensi ke variabel$a
; jika Anda mengganti=&
dengan yang normal=
, itu bukan referensi, dan masih menunjuk ke objek asli.Jawabannya biasanya ditemukan di buku-buku Jawa.
kloning: Jika Anda tidak menimpa metode klon, perilaku default adalah salinan dangkal. Jika objek Anda hanya memiliki variabel anggota primitif, itu benar-benar ok. Tetapi dalam bahasa tanpa jenis dengan objek lain sebagai variabel anggota, itu sakit kepala.
serialisasi / deserialisasi
$new_object = unserialize(serialize($your_object))
Ini mencapai salinan dalam dengan biaya yang besar tergantung pada kompleksitas objek.
sumber
$a = clone $b
, tanpa ada__clone()
metode ajaib dalam permainan) setara dengan melihat masing-masing properti objek$b
dalam istilah, dan menugaskan ke properti yang sama di anggota baru dari kelas yang sama, menggunakan=
. Properti yang merupakan objek tidak akan mendapatkanclone
d, juga objek di dalam array; hal yang sama berlaku untuk variabel terikat oleh referensi; yang lainnya hanyalah nilai, dan akan disalin seperti halnya dengan tugas apa pun.Call to method __clone from invalid context
:)$new_date = (clone $date_start)->subDays(1);
Gagal dengan()
, jika saya menghapusnya, saya mendapatkan kesalahan yang berbeda. Masalahnya, kita menggunakan php 7.2.3 yang sama persis dan milikku berfungsi dengan baik. Ada ide? Dicari di mana-mana ..Menurut komentar sebelumnya, jika Anda memiliki objek lain sebagai variabel anggota, lakukan hal berikut:
Sekarang Anda bisa melakukan kloning:
sumber
Menurut dokumen ( http://ca3.php.net/language.oop5.cloning ):
sumber
Hanya untuk memperjelas PHP menggunakan copy on write, jadi pada dasarnya semuanya adalah referensi sampai Anda memodifikasinya, tetapi untuk objek Anda perlu menggunakan klon dan metode ajaib __clone () seperti pada jawaban yang diterima.
sumber
Kode ini membantu mengkloning metode
sumber
Saya sedang melakukan beberapa pengujian dan mendapatkan ini:
sumber
Dalam contoh ini kita akan membuat kelas iPhone dan membuat salinan persisnya dengan kloning
sumber
Jika Anda ingin sepenuhnya menyalin properti objek dalam contoh berbeda, Anda mungkin ingin menggunakan teknik ini:
Serialize ke JSON dan kemudian de-serialisasi kembali ke Object.
sumber