2012-02-24 6 views
6

Ben kod darbe çalıştırdığınızda:Dizi öğesi değiştiğinde niçin bir değer elemanına (daha önce atanmış bir referanstan sonra) değişiklik atanan bir değişken değişir?

$var[0] = 'a'; 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

çıktısı:

$var[0] = 'a'; 
$foo = & $var[0]; # added line 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

çıkışı olur:

array(1) { [0]=> &string(1) "b" } 

array(1) { [0]=> string(1) "a" } 

şöyle bir satır eklediğinizde

Bir dizinin eleman $var[0] referans alınarak bir değişken $foo atarsanız, böyle değiştirmek gerekiyordu diziye $var için değerli tarafından atanan değişken $tmp mı? Bu neden oluyor?

+0

Çeşitli "pass-by-*" terimlerinin yalnızca işlev bağımsız değişkenleri için geçerli olduğunu unutmayın.Burada geçen hiçbir değişken yok, sadece ödev. – outis

cevap

3

Yasal Uyarı: Bunun için açık bir referans bulmak mümkün olmamıştır, bu yüzden çoğunlukla burada çıkarım ediyorum.

Düzenli bir başvuru sembolü, sembol tablosunda çalışır. Bir değişken ve bir değer oluştururken, her ikisi de çok gibi yerel simge tabloda depolanır:

$bar =& $foo; 

+------------+-------+ 
| symbol  | value | 
+------------+-------+ 
| $foo, $bar | "bar" | 
+------------+-------+ 
:

referans oluşturulur
$foo = "bar"; 

+--------+-------+ 
| symbol | value | 
+--------+-------+ 
| $foo | "bar" | 
+--------+-------+ 

, bu sadece tabloya aynı değer için başka bir sembol ekler

Dizi tuşları farklı olsa saklanır: Orada $var sembolü tablosunda bir giriş, ama dizinin içindeki değerleri tek tek başvurulan

$var[0] = 'a'; 

+--------+-----------------+ 
| symbol | value   | 
+--------+-----------------+ 
| $var | array(0 => 'a') | 
+--------+-----------------+ 

sembol tablosu.

$foo =& $var[0]; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
+--------+------------------+ 
: ne ( $var[0] saklanır) değeri 'a' bir başvuru oluştururken oluyor gerekir sonucuna değeri 'a' $var ve $var[0] kendisi 'a' nereye depolandıklarına yeni bir konuma referans olur dizi ayrılmış olmasıdır

Ben bu nedenle bu bir dizi elemanı için başvuru oluşturmak için tek yoldur, sembol tablosunun iç uygulama dizi anahtarları doğrudan referans oluşturmak izin vermez sanırım. $tmp için $var kopyalama sırasında

Böylece, referans bununla kopyalanır: $var[0] belirtmektedir değeri değiştirirken

$tmp = $var; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
| $tmp | array(0 => %REF) | 
+--------+------------------+ 

Daha sonra, her iki $tmp ve $var bakınız %REF değerini değiştirir. Dediğim gibi

, şu ya da dahili olarak neler olduğunu doğru bir açıklama olabilir veya olmayabilir, ama bu prensibi göstermektedir.