是否等效于PHP中的Function.prototype.apply?

时间:2018-10-30 11:42:53

标签: php function this

在Javascript中,您可以使用this控制apply关键字引用的对象。在以下示例中,将使用等于foo的{​​{1}}来调用this

bar

有什么方法可以在PHP中达到相同的效果吗?仅仅创建在类外部引用function foo() { console.log(this); } let bar = {}; foo.apply(bar); 的函数似乎是可行的,但是(毫无疑问)它就像任何未定义的变量一样被对待。

我知道call_user_func_array,但是它不允许我分配给$this。我认为反射在这里可能有用,但是我不确定如何使用。

2 个答案:

答案 0 :(得分:2)

您可以在注释中看到,PHP $this是指对象上下文,它可能与JavaScript上下文不同。

但是,谈到范围,您可以使用承载对象范围的闭包。该范围位于$ this变量内,可以使用Closure::bindToClosure::bind进行更改。

他们两个都有改变封闭范围的意图。这意味着要更改$this变量中的对象。

下面是一个简单的示例:

class Foo
{
    private $number;

    public function __construct($number)
    {
        $this->number = $number;
    }

    public function getClosure()
    {
        return function() {
            echo $this->number;
        };
    }        
}

及其用途:

$foo = new Foo(10);
$closure = $foo->getClosure();
$closure();

输出:

  

10

数字10是来自$number实例的Foo类内的$foo私有变量的值。

更改范围,从其他实例访问同一变量时,我们可以获得不同的结果:

$foo = new Foo(10);
$foo2 = new Foo(50);
$closureFoo = $foo->getClosure();
$closureFoo();//First execution

echo ' and ';

$closureFoo2 = $closureFoo->bindTo($foo2);
$closureFoo2();//Second execution

输出:

  

10和50

如果您想使用Closure::bind,那就是代码:

$closureFoo2 = Closure::bind($closureFoo , $foo2);

您可以在此处找到更多示例:https://stackoverflow.com/a/40772588/1628790

答案 1 :(得分:1)

利用其他答案和评论的见解,我想到了apply在PHP中的实现:

function apply($func, $new_this, ...$args) {
    Closure::fromCallable($func)->bindTo($new_this)(...$args);
}

不确定这是否有用。但是,可以做到。请注意,这仅在$new_this是对象而不是例如字符串或数字。