call_user_func、call_user_func_array回调函数

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写法  喜欢以参数的形式传递。



关于call_user_func( ) 和 $_session的疑惑

11-27

下面是1.php的部分代码rn[code=php]rnclass Arnrn var $afterEditFun;rn function editRow()rn rn //.......rn if($result)rn rn if(!empty($this->afterEditFun) && is_callable($this->afterEditFun))rn rn call_user_func($this->afterEditFun,$idArr,$this->primaryKeyCol,$afterEditArray);rn rn rnrn rn rn function setConfig($var,$value) //e.g. $var=afterEditFun, $value=array(&$this,'sendNotice')rn rn if($var == 'varPrefix') //varPrefix=id-tablenamern rn // If the variable prefix changed, update variables with session valuesrn $varPrefix = $value;rn foreach($_SESSION as $sessKey => $sessValue)rn rn if(substr($sessKey,0,strlen($varPrefix)) == $varPrefix)rn rn $varName = str_replace($varPrefix,'',$sessKey);rn $this->$varName = $sessValue;rn rn rn rn if(!isset($_SESSION[$this->varPrefix.$var])) //$_SESSION[id-tablename.afterEditFun]rn rn $this->$var = $value; //$this->afterEditFun = array(&$this,'sendNotice')rn rn rnrn[/code]rnrn下面是2.phprn[code=php]rnrequire_once('php/A.php');rnfunction ()rnrn//........rn $Editor = new A( );rn $Editor->setConfig('afterEditFun',array(&$this,'sendNotice'));rn//.........rnrnfunciton sendNotic()rnrn//..............rn rn[/code]rnrn非常疑惑。。在1.php调用call_user_func($this->afterEditFun,$idArr,$this->primaryKeyCol,$afterEditArray); 搜了下afterEditFun除了在成员变量声明外,1.php其他地方都没有。rn在2.php调用了1.php的setConfig()方法,关于这个方法不是太明白。。能有人讲解一下吗??

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试