2012-02-24 25 views
6

Khi tôi chạy đòn mã:Tại sao một biến được gán bởi giá trị cho một phần tử mảng (sau khi một thay đổi-by-tham chiếu trước đó) thay đổi khi phần tử mảng được thay đổi?

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

đầu ra là:

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

Khi tôi thêm một dòng như sau:

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

đầu ra trở thành:

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

Nếu tôi gán một biến $foo bằng cách tham chiếu đến phần tử của mảng $var[0], là biến số $tmp được gán bởi giá trị cho mảng $var phải thay đổi như vậy? Lý do tại sao điều này xảy ra?

+0

Lưu ý rằng các cụm từ "pass-by- *" khác nhau chỉ áp dụng cho các đối số hàm.Không có biến nào chuyển qua đây, chỉ phân công. – outis

Trả lời

3

Tuyên bố từ chối trách nhiệm: Tôi không thể tìm thấy tham chiếu rõ ràng cho điều này, vì vậy tôi chủ yếu suy luận ở đây.

Tham chiếu thường xuyên hoạt động thông qua bảng biểu tượng. Khi tạo một biến và một giá trị, cả hai đều được lưu trữ trong bảng biểu tượng địa phương như vậy:

$foo = "bar"; 

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

Khi một tham chiếu được tạo ra, điều này chỉ đơn giản là thêm biểu tượng khác cho cùng một giá trị để bàn:

$bar =& $foo; 

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

phím mảng được lưu trữ khác nhau mặc dù:

$var[0] = 'a'; 

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

Có một mục trong bảng biểu tượng cho $var, nhưng các giá trị bên trong mảng không được tham chiếu riêng trong bảng biểu tượng. Những gì tôi suy ra phải xảy ra khi tạo một tham chiếu đến giá trị 'a' (lưu trữ trong $var[0]) là giá trị 'a' được tách ra từ mảng $var$var[0] bản thân trở thành một tham chiếu đến vị trí mới của nơi 'a' được lưu trữ:

$foo =& $var[0]; 

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

Tôi đoán rằng việc triển khai nội bộ bảng biểu tượng không cho phép tạo tham chiếu trực tiếp đến các khóa mảng, do đó đây là cách duy nhất để tạo tham chiếu đến phần tử mảng.

Vì vậy, khi sao chép $var-$tmp, tài liệu tham khảo được sao chép với nó:

$tmp = $var; 

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

Sau đó, khi thay đổi giá trị $var[0] đề cập đến, nó thay đổi giá trị của %REF, mà cả hai $tmp$var tham khảo.

Như tôi đã nói, điều này có thể hoặc không thể giải thích chính xác những gì đang diễn ra trong nội bộ, nhưng nó minh họa nguyên tắc.

Các vấn đề liên quan