2012-02-17 30 views
19

Trong PHP 5, bạn có bắt buộc phải sử dụng công cụ sửa đổi & để chuyển qua tham chiếu không? Ví dụ,Làm thế nào để bạn vượt qua các đối tượng bằng cách tham chiếu trong PHP 5?

class People() { } 
$p = new People(); 
function one($a) { $a = null; } 
function two(&$a) { $a = null;) 

Trong PHP4 bạn cần các & sửa đổi để duy trì tài liệu tham khảo sau khi một sự thay đổi đã được thực hiện, nhưng tôi đang bối rối về các chủ đề Tôi đã đọc về việc sử dụng tự động PHP5 của pass-by-reference, ngoại trừ khi explicity nhân bản đối tượng.

Trong PHP5, là modifier&cần thiết để vượt qua bằng cách tham khảo cho tất cả các loại của các đối tượng (biến, các lớp học, mảng, ...)?

+3

Hướng dẫn sẽ giải quyết tất cả các sự cố của bạn. http://php.net/manual/en/language.oop5.references.php – rdlowrey

Trả lời

76

được bạn yêu cầu sử dụng modifier & để pass-by-reference?

Về mặt kỹ thuật/ngữ nghĩa, câu trả lời là , ngay cả với các đối tượng. Điều này là do có hai cách để chuyển/gán một đối tượng: bằng cách tham chiếu hoặc theo số số nhận dạng. Khi khai báo hàm chứa một số &, như sau:

function func(&$obj) {} 

Đối số sẽ được chuyển qua tham chiếu, bất kể là gì. Nếu bạn khai báo mà không có sự &

function func($obj) {} 

Mọi thứ sẽ được truyền theo giá trị, với ngoại lệ của các đối tượng và các nguồn lực, mà sau đó sẽ được chuyển qua định danh. Định danh là gì? Vâng, bạn có thể nghĩ về nó như là một tham chiếu đến một tham chiếu. Lấy ví dụ sau:

class A 
{ 
    public $v = 1; 
} 

function change($obj) 
{ 
    $obj->v = 2; 
} 

function makezero($obj) 
{ 
    $obj = 0; 
} 

$a = new A(); 

change($a); 

var_dump($a); 

/* 
output: 

object(A)#1 (1) { 
    ["v"]=> 
    int(2) 
} 

*/ 

makezero($a); 

var_dump($a); 

/* 
output (same as before): 

object(A)#1 (1) { 
    ["v"]=> 
    int(2) 
} 

*/ 

Vậy tại sao không $a đột nhiên trở thành một số nguyên sau khi chuyển nó đến makezero? Đó là bởi vì chúng tôi chỉ ghi đè số nhận dạng .Nếu chúng ta đi ngang qua tham khảo:

function makezero(&$obj) 
{ 
    $obj = 0; 
} 

makezero($a); 

var_dump($a); 

/* 
output: 

int(0) 

*/ 

Bây giờ $a là một số nguyên. Vì vậy, có sự khác biệt giữa việc chuyển qua số nhận dạng và chuyển qua số tham chiếu.

+11

Cảm ơn bạn đã giải thích sự khác biệt giữa số nhận dạng và tham chiếu, hướng dẫn không rõ ràng về điều này. –

+6

giải thích rất hữu ích và rõ ràng! – skyfree

+0

Đây là cách các đối tượng javascript được truyền theo mặc định. –

0

Bạn đang sử dụng sai. Dấu $ là bắt buộc đối với bất kỳ biến nào. Nó nên là: http://php.net/manual/en/language.references.pass.php

function foo(&$a) 
{ 
$a=null; 
} 


foo($a); 
To return a reference, use 

function &bar($a){ 
$a=5; 
return $a 

} 

Trong các đối tượng và mảng, một tham chiếu đến đối tượng được sao chép như các tham số chính thức, bất kỳ hoạt động bình đẳng trên hai đối tượng là một trao đổi tài liệu tham khảo.

$a=new People(); 
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a 

function goo($obj){ 
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e 
} 
$e=new People(); 
goo($e); 
+0

Tôi quên ký hiệu '$', xin lỗi. –

+0

và tôi quên đọc câu hỏi, xin lỗi. Xem chỉnh sửa của tôi –

0

Đối tượng sẽ không được tham chiếu. Các loại được tạo sẵn sẽ được truyền theo giá trị (được sao chép);

Điều xảy ra đằng sau hậu trường là khi bạn chuyển vào một biến chứa đối tượng, đó là tham chiếu đến đối tượng. Vì vậy, biến tự nó được sao chép, nhưng nó vẫn tham chiếu cùng một đối tượng. Vì vậy, về cơ bản có hai biến, nhưng cả hai đều trỏ đến cùng một đối tượng. Các thay đổi được thực hiện cho các đối tượng bên trong một hàm sẽ vẫn tồn tại.

Trong trường hợp của mã mà bạn có ở đó (trước hết bạn cần $ ngay cả với &):

$original = new Object(); 

one($original); //$original unaffected 
two($original); //$original will now be null 

function one($a) { $a = null; } //This one has no impact on your original variable, it will still point to the object 

function two(&$a) { $a = null;) //This one will set your original variable to null, you'll lose the reference to the object. 
+0

Vì vậy, số nguyên, chuỗi, ký tự và booleans là pass-by-value, trừ khi sử dụng '&' modifier? –

+0

@BrianGraham yes. Nếu bạn đã quen thuộc với con trỏ trong C/C++ $ gốc trong ví dụ trước là loại như thế. Nó chứa một địa chỉ cho Object mà chúng ta tạo ra. $ Bản thân gốc được sao chép khi được chuyển vào hàm một ($ a), nhưng vì nó giữ một địa chỉ mà bản sao đang trỏ vào cùng một đối tượng. – Chris

+0

Bạn nói rằng trong các đối tượng PHP5 được truyền theo tham chiếu, phải không? Sau đó, tại sao bạn sử dụng '&' modifier để chứng minh quan điểm của bạn nếu nó không cần thiết, nó không giúp tôi hiểu câu hỏi của tôi. –

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