2010-06-13 38 views
7

Tôi chỉ mới bắt đầu với PHP và tôi tự hỏi liệu có cách nào để thêm một hàm ẩn danh vào một cá thể lớp hay không.php Đặt chức năng ẩn danh trong một cá thể

Ví dụ, cho phép nói ...

class A{ 
    public B; 
} 

$c = new A(); 

//This is where I am getting a little confused... 
//The following wont work 

$c->B = function(){echo('HelloWorld');}; 
$c->B(); 

Những gì tôi hy vọng sẽ làm được tái sử dụng nước bọt cùng một mã trong một số lượng lớn các ứng dụng khác nhau, và làm cho nó để tôi có thể chỉ 'hoán đổi -out 'và thay thế các hàm trong các trường hợp cụ thể.

Tôi đang sử dụng php5.3 (vì vậy các chức năng ẩn danh sẽ hoạt động, không giống như cách tôi đang sử dụng chúng).

Cảm ơn rất nhiều vì đã dành thời gian của bạn !!

-GK

+0

Bạn có thể đi vào chi tiết về các ứng dụng khác nhau mà bạn đang cố triển khai không? Tôi nghĩ rằng thừa kế đơn giản có thể là một giải pháp tốt hơn, nhưng nhiều thông tin hơn sẽ hữu ích. –

+0

Có thể trùng lặp: http://stackoverflow.com/questions/2938004/how-to-add-a-new-method-to-a-php-object-on-the-fly –

+0

GK tại đây, @Tim Cooper I đang làm việc ở phía máy chủ cho một trò chơi mà tôi đang làm việc và máy chủ sẽ được tạo thành từ hàng tá và hàng tá ứng dụng sẽ quản lý các phần khác nhau của trò chơi. Tất cả chúng sẽ rất giống nhau, và sử dụng nhiều lớp giống nhau, tuy nhiên tất cả chúng sẽ cần khả năng thực thi các chức năng tùy chỉnh ... Tóm tắt Tôi biết, ... Cảm ơn sự giúp đỡ của bạn! @ dev-null-dweller Tôi nghĩ rằng quyền của bạn, tôi đã cố gắng tìm kiếm vấn đề này trước, nhưng rõ ràng là tôi không nhìn đủ cứng, Cảm ơn !! – geekay

Trả lời

9

Bạn có thể sử dụng chức năng ma thuật __call cho công việc này. Không phải là một vẻ đẹp, nhưng nó hoạt động ..

như thế này:

class A { 
    public $B; 

    public function __call($closure, $args) 
    { 
     call_user_func_array($this->$closure, $args); 
    } 
} 

$c = new A(); 

$c->B = function() { echo('HelloWorld'); }; 
$c->B(); 
+0

gk Ở đây, tôi sẽ xem xét điều này ... Tôi sẽ cần phải tìm ra những gì đang làm ... Cảm ơn rất nhiều vì đã chỉ cho tôi đúng hướng! – geekay

+0

được chỉnh sửa để hoàn nguyên phần ghi đè. Tôi thấy bạn đăng chính xác giải pháp giống như user358390 (trừ một sự khác biệt nhỏ), nhưng tôi đã không nhận thấy thời gian quá gần, vì vậy tôi cho lợi ích của sự nghi ngờ – Artefacto

1

Bạn có thể làm một cái gì đó dọc theo những dòng (mà cũng sẽ làm việc với callbacks mà không phải là đóng cửa):

<?php 
class A { 
    private $fun; 
    function setFun($fun) { 
     if (!is_callable($fun)) 
      throw new InvalidArgumentException(); 
     $this->fun = $fun; 
    } 
    public function fun() { 
     call_user_func_array($this->fun, func_get_args()); 
    } 
} 

$c = new A(); 

$c->setFun(function($a) { echo('HelloWorld ' . $a);}); 
$c->fun("here"); 

mang đến cho HelloWorld here.

Điều đó nói rằng, bạn cũng nên xem xét thừa kế hoặc decorator pattern.

2

Có vẻ như bạn đang mô tả một số Strategy Pattern hoặc Decorator Pattern - có otherways để đạt được điều này theo cách dễ dàng liên lạc với các nhà phát triển khác đọc mã của bạn.

4
# real ugly, but PoC... 

class a { 
    function __call($f, $x) { 
    call_user_func_array($this->$f, $x); 
    } 
} 

$a = new a; 
$a->b = function() { echo "Hello world"; }; 
$a->b(); 
4

FWIW:

PHP 5.3 của điều trị chức năng ẩn danh là giải trí. Điều này sẽ không làm việc:

$c->B = function() { echo func_get_arg(0); }; 
$c->B("This fails :("); 

này SẼ làm việc:

$c->B = function() { echo func_get_arg(0); }; 
$hilarious = $c->B; 
$hilarious("This works!"); 

Để làm việc xung quanh này, bạn cần phải sử dụng một __call Hack như một provided by Oden.

Hành vi này có thể thay đổi trong tương lai. array dereferencing RFCrecently committed to PHP's trunk và bản vá đã đặt ra một cuộc thảo luận trên function call chaining, cú pháp trong đó có thể cho phép những gì bạn đang cố gắng thực hiện mà không cần hack __call. Thật không may nó là proven difficult in the past để có được chức năng gọi chuỗi làm việc.

+1

Điều gì là sai với chỉ sử dụng phương pháp vui nhộn? – mukunda

+0

Nó không * sai *, chỉ xấu xí và hacky. – Charles

0

Thay vì gắn phương pháp ma thuật __call vào lớp học của bạn, bạn có thể thực hiện cuộc gọi trực tiếp bằng cách sử dụng call_user_func.

class A { 
    public $b; 
} 

$c = new A(); 
$c->b = function(){echo('HelloWorld');}; 

call_user_func($c->b); // HelloWorld 

Rõ ràng là PHP sẽ cung cấp một số cú pháp để thực hiện điều này trực tiếp.

1

Đây không phải là vấn đề nữa của PHP 7;

// no error 
$result = ($this->anonFunc)(); 
$result = ($this->anonFunc)($arg1, $arg2, ...); 

Xem thêm về AST.

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