Rumah > pembangunan bahagian belakang > tutorial php > php自定义函数的回调函数用法详解

php自定义函数的回调函数用法详解

伊谢尔伦
Lepaskan: 2023-03-11 13:42:01
asal
2620 orang telah melayarinya

 最近在开发一个PHP系统,为了提高系统的扩展性,我想在系统中加入类似Javascript事件处理机制,例如:我想在一篇新闻被添加以后,我想记录一下日志,用类似Javascript的代码,应该是这样写的:

function fnCallBack( $news )
{
     //将$news的信息记录到日志中
    writeLog( $news->getTitle().' has been added successfully!');
}
$newsEventManager->addEventListener( 'add' , fnCallBack );
Salin selepas log masuk

其中,fnCallBack函数是回调函数,addEventListener表示监听newsEventManager的add事件。当一篇news被add以后,系统就会调用fnCallBack函数,从而完成writeLog的动作。

但是,PHP中的函数传递方法和Javascript有很大的不同。在Javascript中,函数也是对象,它可以很方便的当作参数传递,但是PHP不行。

$newsEventManager->addEventListener( 'add' , fnCallBack );
Salin selepas log masuk

上面这行代码中的fnCallBack,看上去好像是那个函数的句柄,但实质上它是一个字符串,并不是我们所要的函数。

为了实现我们的事件模型,有必要研究一下PHP的回调函数的实现方法。

1. 全局函数的回调

这里的全局函数的意思,是直接使用function定义的函数,它不包含在任何对象或类之中。请看下面的例子

示例代码:

function fnCallBack( $msg1 , $msg2 )
{
    echo 'msg1:'.$msg1;
    echo "<br />\n";
    echo &#39;msg2:&#39;.$msg2;
}
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
call_user_func_array( $fnName , $params );
Salin selepas log masuk

代码说明:
这里使用了PHP内置的函数call_user_func_array来进行调用。call_user_func_array有两个参数,第1个参数是一个字符串,表示要调用的函数名,第2个参数是一个数组,表示参数列表,按照顺序依次会传递给要调用的函数。

2. 类的静态方法的回调

如果我们要回调的方法,是一个类的静态方法,那怎么办呢?我们依然可以利用PHP内置的call_user_func_array方法来进行调用,请看示例:
示例代码:

class MyClass
{
    public static function fnCallBack( $msg1 , $msg2 )
    {
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$className = &#39;MyClass&#39;;
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
call_user_func_array( array( $className , $fnName ) , $params );
Salin selepas log masuk

代码说明:
这段代码和第1种方法的代码很相似,我们将类名(MyClass)也作为call_user_func_array的第1个参数传递进去,就可以实现类的静态方法的回调了。注意,这时call_user_func_array的第1个参数是一个数组了,数组的第1个元素是类名,第二个元素是要调用的函数名

3. 对象的方法的回调
先用最原始的字符串形式的调用方法尝试了一下,如下所示:

class MyClass
{
    private $name = &#39;abc&#39;;
    public function fnCallBack( $msg1 = &#39;default msg1&#39; , $msg2 = &#39;default msg2&#39; )
    {
        echo &#39;object name:&#39;.$this->name;
        echo "<br />\n";
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
$myobj->$fnName();
Salin selepas log masuk

调用是成功了,不过如何把参数params传给这个方法呢,如果把params直接传进去,那么它会作为1个参数,怎么把params拆开来传进去呢?
查了下PHP手册,找到了create_function函数,这个方法可以用字符串来创建一个匿名函数,好,有思路了,可以创建一个匿名的函数,在这个匿名函数中,调用我们的回调函数,并把参数传进去。

先手动创建一个匿名函数anonymous,在这个函数中,用前面试出来的方法调用回调函数,如下所示:

class MyClass
{
    private $name = &#39;abc&#39;;
    public function fnCallBack( $msg1 = &#39;default msg1&#39; , $msg2 = &#39;default msg2&#39; )
    {
        echo &#39;object name:&#39;.$this->name;
        echo "<br />\n";
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
function anonymous()
{
    global $myobj;
    global $fnName;
    global $params;
    $myobj->$fnName( $params[0] , $params[1] );
}
anonymous();
Salin selepas log masuk

然后,我用create_function来创建这个匿名函数,同时,代码中的params[0],params[1]应该是动态生成的,代码如下:

$strParams = &#39;&#39;;
$strCode = &#39;global $myobj;global $fnName;global $params;$myobj->$fnName(&#39;;
for ( $i = 0 ; $i < count( $params ) ; $i ++ )
{
    $strParams .= ( &#39;$params[&#39;.$i.&#39;]&#39; );
    if ( $i != count( $params )-1 )
    {
        $strParams .= &#39;,&#39;;
    }
}
$strCode = $strCode.$strParams.");";
$anonymous = create_function( &#39;&#39; , $strCode);
$anonymous();
Salin selepas log masuk

这段代码可以定义一个匿名函数,并保存在$anonymous变量中,最后调用这个$anonymous,实现了方法的回调。

Atas ialah kandungan terperinci php自定义函数的回调函数用法详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan