1) Ketika sebuah array dilewatkan sebagai argumen ke metode atau fungsi, apakah dilewatkan oleh referensi, atau dengan nilai?
2) Saat menetapkan array ke suatu variabel, apakah variabel baru tersebut merupakan referensi ke array asli, atau apakah itu salinan baru?
Bagaimana dengan melakukan ini:
$a = array(1,2,3);
$b = $a;
Apakah $b
referensi untuk $a
?
Jawaban:
Untuk bagian kedua dari pertanyaan Anda, lihat halaman array manual , yang menyatakan (mengutip) :
Dan contoh yang diberikan:
Untuk bagian pertama, cara terbaik untuk memastikan adalah mencoba ;-)
Pertimbangkan contoh kode ini:
Ini akan memberikan output ini:
Yang menunjukkan fungsi belum mengubah array "luar" yang dilewatkan sebagai parameter: itu dilewatkan sebagai salinan, dan bukan referensi.
Jika Anda ingin itu dilewatkan dengan referensi, Anda harus memodifikasi fungsinya, dengan cara ini:
Dan hasilnya akan menjadi:
Seperti, kali ini, array telah lulus "dengan referensi".
Jangan ragu untuk membaca bagian yang Dijelaskan Referensi dalam manual: ini akan menjawab beberapa pertanyaan Anda ;-)
sumber
&
, ya, itu harus - lihat php.net/manual/en/…Sehubungan dengan pertanyaan pertama Anda, array dilewatkan dengan referensi KECUALI itu dimodifikasi dalam metode / fungsi yang Anda panggil. Jika Anda mencoba untuk memodifikasi array dalam metode / fungsi, salinannya dibuat terlebih dahulu, dan kemudian hanya salinan yang dimodifikasi. Ini membuatnya seolah-olah array dilewatkan oleh nilai padahal sebenarnya tidak.
Sebagai contoh, dalam kasus pertama ini, walaupun Anda tidak mendefinisikan fungsi Anda untuk menerima $ my_array dengan referensi (dengan menggunakan karakter & dalam definisi parameter), ia masih dilewatkan oleh referensi (yaitu: Anda tidak membuang-buang memori dengan salinan yang tidak perlu).
Namun jika Anda memodifikasi array, salinannya dibuat terlebih dahulu (yang menggunakan lebih banyak memori tetapi membuat array asli Anda tidak terpengaruh).
FYI - ini dikenal sebagai "copy malas" atau "copy-on-write".
sumber
TL; DR
a) metode / fungsi hanya membaca argumen array => referensi implisit (internal)
b) metode / fungsi memodifikasi argumen array => nilai
c) argumen metode / fungsi array secara eksplisit ditandai sebagai referensi (dengan ampersand) => referensi eksplisit (lahan pengguna)
Atau ini:
- param array non-ampersand : disahkan oleh referensi; operasi penulisan mengubah salinan array yang baru, salinan yang dibuat pada penulisan pertama;
- parameter array ampersand : disahkan oleh referensi; operasi penulisan mengubah array asli.
Ingat - PHP melakukan copy- nilai saat Anda menulis ke param array non-ampersand. Itu
copy-on-write
artinya. Saya ingin menunjukkan sumber C perilaku ini kepada Anda, tetapi menakutkan di sana. Lebih baik gunakan xdebug_debug_zval () .Pascal MARTIN benar. Kosta Kontos bahkan lebih.
Menjawab
Tergantung.
Versi panjang
Saya pikir saya menulis ini untuk diri saya sendiri. Saya harus punya blog atau sesuatu ...
Setiap kali orang berbicara tentang referensi (atau petunjuk, dalam hal ini), mereka biasanya berakhir dengan gegabah (lihat saja utas ini !).
PHP menjadi bahasa yang terhormat, saya pikir saya harus menambahkan hingga kebingungan (meskipun ini ringkasan jawaban di atas). Karena, walaupun dua orang bisa benar pada saat yang sama, Anda lebih baik hanya memecahkan kepala bersama menjadi satu jawaban.
Pertama-tama, Anda harus tahu bahwa Anda bukan seorang yang jago jika Anda tidak menjawab dengan cara hitam-putih . Hal-hal lebih rumit daripada "ya / tidak".
Seperti yang akan Anda lihat, keseluruhan hal berdasarkan nilai / referensi adalah sangat terkait dengan apa sebenarnya yang Anda lakukan dengan array itu dalam metode / fungsi Anda: membacanya atau memodifikasinya?
Apa kata PHP? (alias "perubahan bijaksana")
The pengguna mengatakan ini (penekanan):
Sejauh yang saya tahu, ketika programmer besar, serius, jujur kepada Tuhan berbicara tentang referensi, mereka biasanya berbicara tentang mengubah nilai referensi itu . Dan itulah yang pembicaraan pengguna tentang:
hey, if you want to CHANGE the value in a function, consider that PHP's doing "pass-by-value"
.Ada kasus lain yang tidak mereka sebutkan: bagaimana jika saya tidak mengubah apa pun - baca saja?
Bagaimana jika Anda meneruskan array ke metode yang tidak secara eksplisit menandai referensi, dan kami tidak mengubah array itu di lingkup fungsi? Misalnya:
Baca terus, sesama pelancong.
Apa yang sebenarnya dilakukan PHP? (alias "memori-bijaksana")
Pemrogram besar dan serius yang sama, ketika mereka menjadi lebih serius, mereka berbicara tentang "optimasi memori" dalam hal referensi. Begitu juga PHP. Karena
PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting
itu sebabnya .Tidaklah ideal untuk melewatkan array BESAR ke berbagai fungsi, dan PHP untuk membuat salinannya (setelah itu apa yang dilakukan "pass-by-value"):
Nah sekarang, jika ini benar-benar nilai pass-by-value, kita akan memiliki 3MB + RAM hilang, karena ada dua salinan dari array itu, kan?
Salah. Selama kita tidak mengubah
$arr
variabel, itu adalah referensi, berdasarkan ingatan . Anda hanya tidak melihatnya. Itu sebabnya PHP menyebutkan referensi pengguna-lahan ketika berbicara tentang&$someVar
, untuk membedakan antara yang internal dan eksplisit (dengan ampersand).Fakta
Begitu,
when an array is passed as an argument to a method or function is it passed by reference?
Saya datang dengan tiga (yeah, tiga) kasus:
a) metode / fungsi hanya membaca argumen array
b) metode / fungsi memodifikasi argumen array
c) argumen metode / fungsi array secara eksplisit ditandai sebagai referensi (dengan simbol untuk 'dan)
Pertama, mari kita lihat berapa banyak memori yang sebenarnya dimakan array (jalankan di sini ):
Itu banyak byte. Bagus.
a) metode / fungsi hanya membaca argumen array
Sekarang mari kita membuat fungsi yang hanya membaca array kata sebagai argumen dan kita akan melihat berapa banyak memori yang dibutuhkan oleh logika pembacaan:
Ingin menebak? Saya mendapat 80! Lihat sendiri . Ini adalah bagian yang dihilangkan manual PHP. Jika
$arr
param benar-benar di-by-value, Anda akan melihat sesuatu yang mirip dengan1331840
byte. Tampaknya itu$arr
berlaku seperti referensi, bukan? Itu karena itu adalah referensi - yang internal.b) metode / fungsi memodifikasi argumen array
Sekarang, mari menulis ke param itu, alih-alih membacanya:
Sekali lagi, lihat sendiri , tapi, bagi saya, itu cukup dekat untuk menjadi 1331840. Jadi dalam hal ini, array yang sebenarnya sedang disalin ke
$arr
.c) argumen metode / fungsi array secara eksplisit ditandai sebagai referensi (dengan ampersand)
Sekarang mari kita lihat berapa banyak memori yang dibutuhkan oleh operasi tulis untuk referensi eksplisit (jalankan di sini ) - perhatikan ampersand pada tanda tangan fungsi:
Taruhan saya adalah Anda mendapatkan 200 maks! Jadi ini memakan sekitar memori sebanyak membaca dari param non-ampersand .
sumber
Secara default
Array objek dilewatkan oleh nilai (array) tetapi setiap objek dilewatkan oleh referensi.
Catatan: Sebagai pengoptimalan, setiap nilai tunggal dilewatkan sebagai referensi hingga dimodifikasi di dalam fungsi. Jika diubah dan nilainya diteruskan dengan referensi, maka disalin dan salinannya dimodifikasi.
sumber
Ketika sebuah array dilewatkan ke metode atau fungsi dalam PHP, itu dilewatkan oleh nilai kecuali Anda secara eksplisit meneruskannya dengan referensi, seperti:
Dalam pertanyaan kedua Anda,
$b
bukan referensi$a
, tetapi salinan$a
.Sama seperti contoh pertama, Anda dapat referensi
$a
dengan melakukan hal berikut:sumber
Utas ini sedikit lebih tua tetapi di sini sesuatu yang baru saja saya temui:
Coba kode ini:
http://codepad.viper-7.com/gwPYMw
Perhatikan tidak ada amp untuk parameter $ params dan masih mengubah nilai $ arr ['date']. Ini tidak benar-benar cocok dengan semua penjelasan lain di sini dan apa yang saya pikirkan sampai sekarang.
Jika saya mengkloning objek $ params ['date'], tanggal ke-2 tetap sama. Jika saya hanya mengaturnya ke string, itu tidak mempengaruhi output.
sumber
Untuk memperluas salah satu jawaban, sub array array multidimensi juga diberikan nilai kecuali jika diteruskan secara eksplisit oleh referensi.
Hasilnya adalah:
sumber
Dalam array PHP diteruskan ke fungsi dengan nilai secara default, kecuali Anda secara eksplisit meneruskannya dengan referensi, seperti yang diperlihatkan cuplikan berikut:
Berikut hasilnya:
sumber