16

我想在 PHP 中实现类似于 ac# 委托方法的东西。一个简短的词来解释我总体上要做什么:我正在尝试实现一些异步功能。基本上,当底层系统处理它时,一些资源密集型调用会被排队、缓存和分派。当异步调用最终收到响应时,我希望引发回调事件。

我在提出一种在 PHP 中进行回调的机制时遇到了一些问题。我想出了一个现在可行的方法,但我对它不满意。基本上,它涉及传递对对象的引用以及将用作回调的方法的名称(将响应作为参数),然后在需要时使用 eval 调用方法。由于各种原因,这是次优的,有没有人知道的更好的方法?

4

3 回答 3

16

(除了观察者模式)你也可以使用call_user_func()or call_user_func_array()

如果您传递array(obj, methodname)as 第一个参数,它将调用 as $obj->methodname()

<?php
class Foo {
    public function bar($x) {
        echo $x;
    }
}

function xyz($cb) {
    $value = rand(1,100);
    call_user_func($cb, $value);
}

$foo = new Foo;
xyz( array($foo, 'bar') );
?>
于 2008-09-07T17:14:11.903 回答
4

你觉得使用观察者模式怎么样?如果没有,您可以通过这种方式实现真正的回调:

// This function uses a callback function. 
function doIt($callback) 
{ 
    $data = "this is my data";
    $callback($data); 
} 


// This is a sample callback function for doIt(). 
function myCallback($data) 
{ 
    print 'Data is: ' .  $data .  "\n"; 
} 


// Call doIt() and pass our sample callback function's name. 
doIt('myCallback'); 

显示:数据是:这是我的数据

于 2008-09-07T17:07:47.443 回答
3

我想知道我们是否可以使用 __invoke 魔术方法来创建“某种”第一类函数,从而实现回调

听起来像这样,对于 PHP 5.3

interface Callback 
{
    public function __invoke(); 
}

class MyCallback implements Callback
{
    private function sayHello () { echo "Hello"; }
    public function __invoke ()  { $this->sayHello(); } 
}

class MySecondCallback implements Callback
{
    private function sayThere () { echo "World"; }
    public function __invoke ()  { $this->sayThere(); }
}

class WhatToPrint
{
    protected $callbacks = array();
    public function register (Callback $callback) 
    {
        $this->callbacks[] = $callback;
        return $this;
    }
    public function saySomething ()
    {
        foreach ($this->callbacks as $callback) $callback(); 
    }
}

$first_callback = new MyCallback;
$second_callback = new MySecondCallback;
$wrapper = new WhatToPrint;
$wrapper->register($first_callback)->register($second_callback)->saySomething();

将打印 HelloWorld

希望它会有所帮助;)

但对于这样的功能,我更喜欢带有 SPL 的控制器模式。

于 2010-07-01T14:45:36.140 回答