2010-10-18 33 views
8

Xin vui lòng xem mã này:Toán tử "&" hoạt động như thế nào trong một hàm PHP?

function addCounter(&$userInfoArray) { 
    $userInfoArray['counter']++; 
    return $userInfoArray['counter']; 
} 

$userInfoArray = array('id' => 'foo', 'name' => 'fooName', 'counter' => 10); 
$nowCounter = addCounter($userInfoArray); 

echo($userInfoArray['counter']); 

này sẽ hiển thị 11.

Nhưng! Nếu bạn xóa toán tử "&" trong thông số hàm, kết quả sẽ là 10.

Điều gì đang xảy ra?

+0

2 câu trả lời hoàn hảo cho chỉ 3 phút! Các bạn có tất cả các genious hay gì đó không? hoặc mong tôi hỏi câu hỏi này. Thật ngạc nhiên! – Deckard

+0

* (liên quan) * [Biểu tượng này có ý nghĩa gì trong PHP] (http://stackoverflow.com/questions/3737139/reference-what-does-this-symbol-mean-in-php) – Gordon

+0

Oh ... I đã cố gắng để google nó, nhưng không thành công ... Vì vậy, bối rối .. – Deckard

Trả lời

22

Toán tử & yêu cầu PHP không sao chép mảng khi chuyển nó vào hàm. Thay vào đó, tham chiếu vào mảng được chuyển vào hàm, do đó hàm sửa đổi mảng gốc thay vì bản sao.

Chỉ cần nhìn vào ví dụ tối thiểu này:

<?php 
function foo($a) { $a++; } 
function bar(&$a) { $a++; } 

$x = 1; 
foo($x); 
echo "$x\n";  
bar($x); 
echo "$x\n"; 
?> 

Ở đây, đầu ra là:

1 
2 

- cuộc gọi đến foo không sửa đổi $x. Các cuộc gọi đến bar, mặt khác, đã làm.

+0

+1 cho ví dụ ngắn gọn – Ross

+0

Cảm ơn câu trả lời hoàn hảo – Deckard

+0

Tôi biết tôi hơi muộn về điều này - nhưng cảm ơn bạn vì câu trả lời cực kỳ rõ ràng này không để lại câu hỏi nào. – Michael

6

Ở đây, nhân vật & có nghĩa là biến được truyền bằng cách tham khảo, thay vì bởi giá trị. Sự khác biệt giữa hai là nếu bạn vượt qua bằng cách tham chiếu, bất kỳ thay đổi nào được thực hiện đối với biến cũng được thực hiện đối với biến gốc.

function do_a_thing_v ($a) { 
    $a = $a + 1; 
} 
$x = 5; 
do_a_thing_v($x); 
echo $x; // echoes 5 

function do_a_thing_r (&$a) { 
    $a = $a + 1; 
} 
$x = 5; 
do_a_thing_v($x); 
echo $x; // echoes 6 
+0

Cảm ơn bạn đã trả lời hoàn hảo – Deckard

2

Khi sử dụng dấu và trước biến trong lệnh gọi hàm, nó liên kết với biến gốc. Với điều đó, mã bạn đã đăng sẽ nói rằng nó sẽ thêm 1 vào bộ đếm của mảng ban đầu. Nếu không có dấu và, phải mất một bản sao của dữ liệu và thêm vào nó, sau đó quay lại đếm mới 11. Các mảng cũ vẫn vẫn còn nguyên vẹn ở mức 10 và các biến truy cập mới được trả về biến thành 11.

http://www.phpreferencebook.com/samples/php-pass-by-reference/

là một ví dụ điển hình.

+0

Thực sự cảm ơn bạn! – Deckard

2

Có lẽ tôi có thể thêm vào các câu trả lời khác, nếu nó là đối tượng, thì đó không phải là "đối tượng được truyền dưới dạng giá trị", nhưng "tham chiếu của đối tượng được chuyển thành giá trị" (mặc dù tôi đang hỏi sự khác biệt giữa "đối tượng được truyền bằng tham chiếu" so với "tham chiếu của đối tượng được chuyển bởi giá trị" trong các nhận xét). Một mảng được truyền theo giá trị theo mặc định.

Thông tin: Objects and references

Ví dụ:

class Foo { 
    public $a = 10; 
} 

function add($obj) { 
    $obj->a++; 
} 

$foo = new Foo(); 
echo $foo->a, "\n"; 

add($foo); 
echo $foo->a, "\n"; 

Kết quả:

$ php try.php 
10 
11 
+0

Cảm ơn bạn Mr.Genious khác. – Deckard

+1

Đây là lỗi thường gặp. Các đối tượng là * không * được truyền qua tham chiếu. Thay vào đó, tham chiếu của chúng được truyền theo giá trị. Đây là một sự khác biệt rất quan trọng! Hãy thử sửa đổi tham chiếu, chứ không phải là một thành viên cá thể (ví dụ: viết '$ obj = new Foo()' bên trong phương thức). Trớ trêu thay, trang bạn liên kết thậm chí * nói * rằng trích dẫn của bạn không đúng! Vì vậy, bạn phải biết rằng bạn đã viết một cái gì đó sai. –

+0

nếu nó được chuyển qua tham chiếu, nếu tham chiếu của nó được truyền theo giá trị, nếu '$ obj = new Foo()' bên trong phương thức, thì các kết quả có giống nhau không? tức là khi in ra một lần nữa, nó vẫn là '11'. –

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