call_user_func 和 call_user_func_array实际上没啥区别,call_user_func比call_func_array运行速度快。前者传参数的形式是call_user_func('回调函数名','参数1','参数2'...)后者就是('回调函数',array) 后者更规范了一些
eg:function a( $params1,$params2 ){
return $params1+params2
}
使用call_user_func( 'a',1,2 ) 使用call_user_func_array('a',[1,2])
关于两个函数的第一个参数 回调函数 可以使用数组
eg:一个类中 调用
class Test {
public function test($a,$b){
return $a * $b;
}
//这个地方使用
pulic function use_call(){
call_user_func([$this,'test'],2,3) || call_user_func_array([$this,'test'],[2,3])
}
}
在某一个类中使用
class Test2{
public function use_call(){
$class = new Test();
call_user_func([$class,'test'],2,3) || call_user_func_array([$class,'test'],[2,3])
}
}
把他延伸到父类我喜欢用来做公共处理:
举例:mysql事务处理 (YII2框架)
父类里定义一个tarnsaction函数
protected function transaction(Callable $call, $db = null) { if (!$db) { $db = Yii::$app->db; } $trans = $db->beginTransaction(); try { $params = func_get_args(); //获取所有参数 array_shift($params); //这个地方删除掉$call参数 array_shift($params); //删除$db参数 call_user_func_array($call, $params); } catch (Exception $e) { $trans->rollBack(); throw $e; } $trans->commit(); return true; }
在子类里继承然后使用该父类的事务处理功能
$this->transaction(function() use ($goods, $goodsAttrs, $delGoodsAttrs) { if (!$goods->save()) { throw new SystemException($goods->errors); } foreach ((array)$goodsAttrs as $attr) { $attr->goods_id = $goods->id; if (!$attr->save()) { throw new SystemException($attr->errors); } } foreach ((array)$delGoodsAttrs as $attr) { if (!$attr->delete()) { throw new SystemException($attr->errors); } } });
上片段代码是放在子类的某方法下 直接调用父类的transaction方法:
transaction(callable 强制回调类型 $call) 在本次实例中 则使用匿名函数的方式 把函数作为参数传递同时使用use PHP5.3及以上可以使用,在匿名函数体中的所有代码都会在父类中
call_user_func_array($call, $params);
被回调执行。
在父类里写了一个
$params = func_get_args(); //获取所有参数 array_shift($params); //这个地方删除掉$call参数 array_shift($params); //删除$db参数
获取参数删除掉前两个 再回传到回调函数 这种做法是在
$this->transaction(function() { ............... },参数1,参数2.....);
可以接收多个参数,在父类里回传到匿名函数处理。不过要在上述函数..........中进行变量的处理;
简言之 使用传多个参数的情景 低版本的PHP不支持use写法 喜欢以参数的形式传递。