PHP闭包函数及函数回调

简介:什么是PHP闭包,回调自定义函数,回调对象方法

1. 匿名函数

在了解回调函数之前我们来了解一下什么是匿名函数?

顾名思义,匿名函数就是一个没有确定函数名的函数,PHP将匿名函数和闭包视作相同的概念,所以匿名函数在PHP中也叫作闭包函数

由于它没有名字,所以他只能被赋值给一个变量,不能单独存在,例如下方案例:

// 定义一个匿名函数
$a = function($v){
    echo $v;
};
// 调用匿名函数
echo $a(1);

注意:匿名函数后面必须要有

在PHP中匿名函数一般都是当作一个参数传给某个函数,例如:array_map(),array_filter(),usort()等一些特殊内置函数。具体使用方式如下方的自定义排序函数:

$arr = [2,1,3,5,4,6];
$callback = function ($a,$b){
    if( $a == $b ) return 0;
    return $a > $b ? 1 : -1;
};
$res = usort($arr,$callback);
var_dump($arr); //排序结果:[1,2,3,4,5,6]

对于上述自定义排序方法,我们还可以简化一下,把匿名函数直接当成参数传给 usort() 函数:

$arr = [2,1,3,5,4,6];

$res = usort($arr,function ($a,$b){
    if( $a == $b ) return 0;
    return $a > $b ? 1 : -1;
});

2. 回调函数

其实这种把自定义函数当成参数传给某个函数,再由函数内部进行回调的方式就叫做函数回调。只是匿名函数是一个特例,匿名函数与回调结合在PHP中成为闭包函数。

除了使用匿名函数之外,我也可以使用自定义函数,方式和上面的匿名函数相似:

$arr = [2,1,3,5,4,6];

function userSort($a,$b){
    if( $a == $b ) return 0;
    return $a > $b ? 1 : -1;
}

$res = usort($arr,'userSort');

注意:自定义函数当成参数传值时是一个字符串的形式,PHP会自动从当前脚本环境中寻找同名函数

3. 对象如何使用函数回调

上面的案例中我们都是回调函数,但是实际开发中我们都是基于面向对象的方式进行开发,那么如何把对象的某个方法当成函数回调进行传值呢?

在PHP中,我们只需要把回调函数以数组的形式传给主函数即可,例如:

<?php

class Sort{
    function userSort($a,$b){
        if( $a == $b ) return 0;
        return $a > $b ? 1 : -1;
    }
}
$arr = [2,1,3,5,4,6];
usort($arr,[(new Sort()),'userSort']);

var_dump($arr); // 执行结果:[1,2,3,4,5,6];

注意:把对象的某个方式当成回调函数时,参数一是当前对象,参数二才是实际回调的方法名

如果是在对象内部使用时,参数一直接使用 $this 代替即可。具体方式如下:

<?php

class Sort{
    function userSort($a,$b){
        if( $a == $b ) return 0;
        return $a > $b ? 1 : -1;
    }
    function go($arr){
        return usort($arr,[$this,'userSort']);
    }
}
$arr = [2,1,3,5,4,6];
(new Sort())->go($arr);

var_dump($arr); //结果值:[1,2,3,4,5,6];

4. 自定义函数中如何实现函数回调

要实现函数回调功能,我们需要使用 call_user_func() 或者 call_user_func_array() 函数。

这两个函数的作用都是回调一个函数,不同的是回调函数时传参方式不同。

有点难理解,我们先来看看下方案例:

function sum1($a,$b,$callback){
    call_user_func($callback,$a,$b);
    call_user_func_array($callback,[$b,$a]);
    return $a + $b;
}

sum1(1,2,function ($a,$b){
    echo 'a的值:'.$a.PHP_EOL;
    echo 'b的值:'.$b.PHP_EOL;
});
// 输出结果:
// a的值:1
// b的值:2
// a的值:2
// b的值:1

上面我们定义了一个计算加法的函数,但是在计算加法之前我们通过回调的形式打印两个变量的值。从使用上看,call_user_func() 函数传参是一个一个按顺序传值,而 call_user_func_array() 函数是把所有参数打包到数组中,数组中的值按顺序依次传值给回调函数

当然了,在使用上我们也可以把对象传过去,具体实现如下:

<?php

function sum1($a,$b,$callback){
    call_user_func($callback,$a,$b);
    call_user_func_array($callback,[$b,$a]);
    return $a + $b;
}

class Test{
    function callback($a,$b){
        echo 'a的值:'.$a.PHP_EOL;
        echo 'b的值:'.$b.PHP_EOL;
    }
    
    function go($a,$b){
        // 对象内部使用
        sum1($a,$b,[$this,'callback']);
    }
}
// 对象外部使用
sum1(1,2,[new Test(),'callback']);

(new Test())->go(1,2);

现在,我们已经了解了它的实现原理,剩下的就是根据业务进行实际业务逻辑编辑实际代码。

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1