php调用外部函数作为内部方法


php call foreign function as internal method

我想在php中创建一个类似jquery的语法,我写了那个类:

class events{
    public function auth($user, $pass, $callback){
        $status = 0;
        if($user and $pass){
            $status = 1;
        }
        call_user_func($callback, $status);
    }
    public function login(){
        echo "Welcome!";
    }
}
$events = new events;
$user = "u";
$pass = "p";

这就是类似Jquery的语法:

/**
 * Jquery type callback function
 */
$events->auth($user, $pass, function($status){
    if($status){
        $this->login();
    }else{
        echo "Fail";
    }
});

除了$this变量之外,一切都很好。我使用了该类的外部方法,我不能将回调函数用作将$this用于该函数代码的内部函数。我能通过改变课堂上的一些内容来纠正那个错误吗?

您需要使用Closure::bind将匿名函数绑定到对象。


示例:

class events{
    public function auth($user, $pass, $callback){
        $status = 0;
        if($user and $pass){
            $status = 1;
        }
        call_user_func(Closure::bind($callback, $this), $status);
    }
    public function login(){
        echo "Welcome!";
    }
}
$events = new events;
$user = "u";
$pass = "p";
$events->auth($user, $pass, function($status){
    if($status){
        $this->login();
    }else{
        echo "Fail";
    }
});

输出:

Welcome!

还需要注意的是,没有必要使用call_user_func(),如果您喜欢,可以用类似的东西替换该行:

$callback = $callback->bindTo($this);
$callback($status);

您可以将类的实例传递给回调:

<?php
class events{
    public function auth($user, $pass, $callback){
        $status = 0;
        if($user and $pass){
            $status = 1;
        }
        $callback($status, $this);
    }
    public function login(){
        echo "Welcome!";
    }
}
$events = new events;
$user = "u";
$pass = "p";

/**
 * Jquery type callback function
 */
$events->auth($user, $pass, function($status, $self){
    if($status){
        $self->login();
    }else{
        echo "Fail";
    }
});

没有办法像JavaScript那样将闭包"绑定"到特定对象。因此,$this关键字不能在类之外使用。但是,由于$events$this将引用的实例,因此可以执行以下操作:

$events->auth($user, $pass, function($status){
    if($status){
        $events->login();
    }else{
        echo "Fail";
    }
});

编辑:显然我错了,有一种方法可以将闭包绑定到特定实例。看看保罗的回答。