2016-01-06 18 views
6

Tôi nghĩ PHP = là một nhiệm vụ giá trị đơn giản. Ví dụ:Tại sao phân bổ PHP hoạt động theo cách này?

$x = 1; 
$a = $x; 
$b = $x; 
$a++; 
echo $a; 
echo $b; 

Sản xuất 21 như mong đợi. Tuy nhiên, các mã dưới đây hoạt động khác nhau sau đó những gì tôi mong đợi. Tôi đã cơ bản cố định giá trị "cùng một" giá trị cho nhiều biến:

class X { 
    public $val = 0; 

    public function doSomething() { 
     $this->val = "hi"; 
    } 
} 

function someFunction() { 
    $template = array('non_object' => 0, 'object' => new X()); 
    $a = $template; 
    $b = $template; 

    //Do something 
    $a['object']->doSomething(); 

    var_dump($a); 
    var_dump($b); 
} 

Tạo:

array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 
array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 

Như bạn có thể thấy object tài sản trong array A thay đổi như mong đợi, mà còn thay đổi trong array B.

Bạn có thể kiểm tra mã ở đây: http://sandbox.onlinephpfunctions.com/code/bff611fc9854b777114d38a3b4c60d524fdf2e19

Làm thế nào tôi có thể gán giá trị như nhau đối với nhiều biến PHP và vận dụng chúng mà không cần phải cho họ trong "lượng tử rối" trạng thái này và không sao chép?

Trả lời

1

Tính đến PHP 5, tất cả các đối tượng được thông qua và bằng cách tham khảo

giao

Hãy lấy mã của bạn bên dưới

$a = $template; 
    $b = $template; 

Lý do tại sao bạn có kết quả bất ngờ:

gì chính xác xảy ra ở đây là, $a$b cũng giống như 'con trỏ' hoặc trỏ 'xử lý' để cùng đối tượng $template và thats lý do bạn gặp một cái gì đó bất ngờ cos bạn đã thay đổi các đối tượng thông qua một trong những tài liệu tham khảo $a và kể từ $b cũng tham chiếu cùng một đối tượng, bạn có nhận thấy sự thay đổi

Từ PHP Manual Objects and References

Một trong những điểm then chốt của OOP PHP5 thường được đề cập là "đối tượng được chuyển bởi tham chiếu theo mặc định".Đây không phải là hoàn toàn đúng. Phần này khắc phục suy nghĩ chung bằng cách sử dụng một số ví dụ.

Tham chiếu PHP là bí danh, cho phép hai biến khác nhau để ghi cùng một giá trị. Kể từ PHP5, một biến đối tượng không chứa chính đối tượng đó làm giá trị nữa. Nó chỉ chứa một đối tượng định danh cho phép đối tượng truy cập tìm thấy đối tượng thực tế. Khi một đối tượng được gửi bởi đối số, trả lại hoặc gán cho biến số khác, các biến khác nhau không phải là bí danh: chúng giữ một bản sao của mã định danh trỏ đến cùng một đối tượng.

5

Bạn đã gán biến $ a và $ b cho cùng một đối tượng. Vì vậy, nếu bạn gọi $a["object"]->doSomething() hoặc $b["object"]->doSomething() sẽ cho kết quả tương tự vì $a["object"]$b["object"] giống nhau.

Nếu bạn cần kết quả đầu ra là khác nhau, hãy thử mã dưới đây:

class X { 
    public $val = 0; 

    public function doSomething() { 
     $this->val = "hi"; 
    } 
} 

function someFunction() { 
    $a = array('non_object' => 0, 'object' => new X()); 
    $b = array('non_object' => 0, 'object' => new X()); 

    //Do something 
    $a['object']->doSomething(); 

    var_dump($a); 
    var_dump($b); 
} 

Output sẽ là như sau:

array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 
array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#2 (1) { 
    ["val"]=> 
    int(0) 
    } 
} 

Ở đây bạn được gán đối tượng khác nhau để $ một một $ b.

Please check this

+2

xem thêm: http://docs.php.net/manual/en/language.oop5.references.php – VolkerK

1

Nếu bạn chỉ muốn gán giá trị, u có thể sử dụng chức năng: clone

class X { 
    public $val = 0; 

    public function increment() { 
    $this->val += 1; 
    } 
} 

function someFunction() { 
    $template =new X(); 
    $a = $template; 
    $b = clone $template; 

    //Increment a 
    $a->increment(); 

    var_dump($a); 
    var_dump($b); 
} 

someFunction(); 

$x = 1; 
$a = $x; 
$b = $x; 

$a++; 
echo $a; 
echo $b; 

check this

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