最近学习到php的回调函数,发现还是蛮难理解的,于是找了度娘查了各种资料来整理出这篇博客。
什么是回调函数
我在网上找了好些解释,找到一个我认为比较合理的适合php的回调函数:
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。
简而言之就是,我在调用函数A(通常是API函数)时需要调用自己写的函数B,这时候一个函数无法作为参数传入函数A,那么就可以将B的地址和执行函数所需的参数打包传入A。这里面称B为回调函数。
如何使用回调函数
使用回调函数有很多种方式,下面我来介绍几种。使用回调函数一般用到php自带的array_user_func()
官方介绍函数。
例1
function callback($a,$b) {
echo "$a,$b";
}
call_user_func('callback',"hello","world");
//输出 hello,world
这是最基本的使用回调函数的办法,相当于是全局函数。
那么,当是一个类中的方法呢?
例2
class hello {
function callback($a,$b) {
echo "$a,$b";
}
}
//将类名作为参数
call_user_func(array('hello','callback'),"hello","world");
//输出 hello,world
//将对象作为参数
call_user_func(array(new hello(),'callback'),"hello","world");
//输出 hello,world
当然如果是静态方法时更简单
例3
class hello {
static function callback($a,$b) {
echo "$a,$b";
}
}
call_user_func('hello::callback',"hello","world");
为什么使用回调函数
利用回调函数,你可以将与组件以及核心任务没有直接关系的功能插入到组件中,在运行中将其插入核心任务中。有了回调,你就赋予了别人别人扩展你代码的权利。
举一个栗子:
class Product{
public $name;
public $price;
function __construct($name,$price){
$this->name=$name;
$this->price=$price;
}
}
class ProcessSale{
private $callbacks;
//定义一个回调函数注册方法,将通过检测的变量存入回调函数数组中
function registerCallback($callback){
if(!is_callable($callback)){
//is_callable函数用于检测变量内容能否作为函数被调用
throw new Exception("callback not callable");
}
$this->callbacks[]=$callback;
}
function sale($product){
print "{$product->name}:processing \n";
foreach ($this->callbacks as $callbacks){
call_user_func($callbacks,$product);
}
}
//创建一个匿名函数
$logger=function($product){
print"logging({$product->name})\n";
};
$processor=new ProcessSale();
$processor->registerCallback($logger);
$processor->sale(new Product("shoes",6));
print "\n";
$processor->sale(new Product("coffee", 6));
?>