PHP回调的用途是什么?

时间:2018-09-07 11:23:11

标签: php callback

我想知道我们什么时候应该使用PHP回调函数,而使用PHP回调函数代替传统函数有什么好处?

例如

使用小写字母获取姓名的传统方式

<?php
function string($string){
    $results = array(
        'upper' => strtoupper($string),
        'lower' => strtolower($string),
    );
    return $result;
}
$name = string('Ahmar');
echo $name; //Output: ahmar
?>

使用回调

获得相同的输出
<?php
function string($string, $callback){
    $results = array(
        'upper' => strtoupper($string),
        'lower' => strtolower($string)
    );
    if(is_callable($callback)){
        call_user_func($calllback, $result);
    }
}
string('Ahmar', function($name){
    echo $name['lower']; //Output: ahmar
});

?>

请解释一下使用闭包回调有什么好处,什么时候应该使用它? 谢谢

2 个答案:

答案 0 :(得分:4)

PHP在回调中几乎没有用,当动作完成后,将被称为 ,例如:

string('Ahmar', function ($name) { echo ... })

这在像Javascript这样的语言中非常惯用;但这是因为Javascript具有与PHP完全不同的执行模式。在Javascript中,通常是同时发生许多事情,要么是由于交互式UI,要么是在浏览器中发生,要么是由于并行请求而在服务器上发生。虽然PHP非交互地在单个线程中运行,所以并没有发生许多需要异步协调的并行任务。 PHP中的并行执行通过不同的PHP实例进行,而不是在同一PHP实例中进行。

在Javascript中,您需要回调来协调在后台发生的事情完成处理后应该发生的事情:

foo(bar => {
    // this happens after
});

// this happens before

在PHP中,只需等待函数返回即可实现相同的目的:

// this happens before
$bar = foo();
// this happens after

(请注意,当然有例外;例如,用PHP编写Web套接字服务器时,您将获得与在node.js中看到的基于回调的体系结构。)

因此,在大多数情况下,当您不仅需要将值作为参数传递给算法时,还需要代码块时,可以使用回调。举一个具体的例子,以usort

usort($foo, function ($a, $b) { return $a['bar'] - $b['bar']; });

此回调与异步执行无关,而是用于将自定义排序逻辑传递给函数。

答案 1 :(得分:-1)

闭包是返回函数的函数。返回的函数是一个匿名函数,然后可以将其分配给变量并作为回调传递。使用闭包的优点之一是,父函数可以执行或跟踪在父函数上定义的某些属性,并且在需要时甚至可以访问该信息,并且可以根据需要实现闭包,而这一切都取决于该函数的定义和实例化方式。

假设您有一个电子商务网站,您的用户信用额度有限,并且您想在用户达到信用额度时对其进行限制或发出警告,那么我们可以像下面这样实现:

class UserCredit
{
    public static function creditLimitWarn($amount){
        $total = 0;
        $creditlimit = $amount;
        return function($purchase) use (&$total,$creditlimit){
            $total += $purchase;
            if($total > $creditlimit){
                echo "Purchase above credit limit:\nYour credit: $creditlimit.\nYour current purchase $total\n";
            }
        };
    }
}

$user = UserCredit::creditLimitWarn(3000);
$user(5000);



// Output:
// Purchase above credit limit:
// Your credit: 3000.
// Your current purchase 5000

然后,您可以将$ user注册为其他类或方法的回调,可能是在处理购买的类中。

如您所见,闭包确实非常强大,问题是要知道在哪里实现闭包,并注意到实现闭包将节省大量代码并可能为应用程序带来一些性能提升的好地方 >