2011-12-05 15 views
80

Các PHP tay bang

Nó không phải là có thể sử dụng $this từ chức năng ẩn danh trước PHP 5.4.0

trên số anonymous functions page. Nhưng tôi đã tìm thấy tôi có thể làm cho nó hoạt động bằng cách gán $this cho một biến và chuyển biến đó tới câu lệnh use ở định nghĩa hàm.

$CI = $this; 
$callback = function() use ($CI) { 
    $CI->public_method(); 
}; 

Đây có phải là phương pháp hay không?
Có cách nào tốt hơn để truy cập $this bên trong một chức năng ẩn danh bằng cách sử dụng PHP 5.3 không?

+1

Quy ước diễn đàn phụ - thường tốt hơn là chấp nhận câu trả lời để chỉnh sửa câu hỏi để phản ánh câu trả lời ưa thích của bạn. Chủ yếu điều này là để phản ứng vẫn có ý nghĩa trong vĩnh cửu, nhưng cũng tất nhiên để cung cấp tín dụng cho một câu trả lời đúng. – halfer

+3

Hãy coi chừng rằng '$ CI = $ this;' và '$ CI = & $ this;' ** không ** thực sự giống hệt nhau. Có thể vì mục đích của bạn, nhưng chúng không giống nhau. Hãy thử '$ CI = 'bla'; var_dump ($ this); 'với cả hai phiên bản để thấy sự khác biệt. – Rudie

+1

@Rudie Tôi đang thêm [tài liệu] (http://php.net/manual/en/language.oop5.references.php) cho nhận xét của bạn – steampowered

Trả lời

61

Nó sẽ thất bại khi bạn cố gắng gọi một phương pháp được bảo vệ hoặc riêng tư trên nó, bởi vì sử dụng nó theo cách đó được tính như gọi từ bên ngoài. Không có cách nào để làm việc xung quanh này trong 5,3 như xa như tôi biết, nhưng đến PHP 5.4, nó sẽ làm việc như mong đợi, out of the box:

class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 
$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 
$helloPrinter(); // outputs "Hello world" 

Thậm chí nhiều hơn, bạn sẽ có thể thay đổi những gì $ điều này dẫn đến khi chạy, cho các chức năng Anonymus (đóng cửa rebinding):

class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 

class Bye { 

    private $message = "Bye world\n"; 

} 

$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 

$bye = new Bye(); 
$byePrinter = $helloPrinter->bindTo($bye, $bye); 
$byePrinter(); // outputs "Bye world" 

hiệu quả, chức năng Anonymus sẽ có một bindTo() method, nơi mà các tham số đầu tiên có thể được dùng để xác định những gì $ điểm này để, và các điều khiển tham số thứ hai mức hiển thị là. Nếu bạn bỏ qua tham số thứ hai, khả năng hiển thị sẽ giống như gọi từ "bên ngoài", ví dụ: chỉ có thể truy cập các thuộc tính công khai. Cũng lưu ý cách bindTo hoạt động, nó không sửa đổi chức năng ban đầu, nó trả về một cái mới.

+1

Đánh dấu câu trả lời đúng, nhưng chỉ để làm rõ cho người đọc khác: quy ước được sử dụng trong câu hỏi sẽ làm việc cho các phương thức công khai bằng cách sử dụng đối tượng đang tham chiếu '$ this'. – steampowered

+5

[Phương pháp phi công cộng] (http://stackoverflow.com/a/6386863/90527) có thể được truy cập bằng cách sử dụng phản chiếu. Không hiệu quả và một chút ác, nhưng nó hoạt động. – outis

1

Điều đó có vẻ ổn nếu bạn đi ngang qua tham chiếu đó là cách chính xác để thực hiện. Nếu bạn sử dụng PHP 5, bạn không cần biểu tượng & trước $this vì nó sẽ luôn chuyển qua tham chiếu bất kể.

+2

OP phải bằng 5.3 hoặc cao hơn, vì 4.x không hỗ trợ chức năng ẩn danh :-) – halfer

1

Điều này là tốt. Tôi nghĩ bạn cũng có thể làm điều này:

$CI = $this; 

... vì việc gán liên quan đến đối tượng sẽ luôn sao chép tham chiếu chứ không phải toàn bộ đối tượng.

5

Đó là cách thông thường được thực hiện.
b.t.w, hãy thử xóa & nó sẽ hoạt động mà không có điều này, vì các đối tượng truyền qua ref theo bất kỳ cách nào.

5

Không phải lúc nào cũng dựa vào PHP để chuyển đối tượng theo tham chiếu, khi bạn chỉ định tham chiếu, hành vi không giống như hầu hết các ngôn ngữ OO mà con trỏ ban đầu được sửa đổi.

ví dụ của bạn:

$CI = $this; 
$callback = function() use ($CI) { 
$CI->public_method(); 
}; 

nên là:

$CI = $this; 
$callback = function() use (&$CI) { 
$CI->public_method(); 
}; 

LƯU Ý CÁC THAM KHẢO "&" và $ CI nên được chỉ định sau khi cuộc gọi cuối cùng về nó đã được thực hiện, một lần nữa khác mà bạn có thể có đầu ra không thể đoán trước, trong PHP truy cập một tham chiếu không phải lúc nào cũng giống như truy cập lớp gốc - nếu điều đó có ý nghĩa.

http://php.net/manual/en/language.references.pass.php

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