Эквивалент Function.prototype.apply в PHP? - PullRequest
0 голосов
/ 30 октября 2018

В Javascript вы можете контролировать, на какой объект ссылается ключевое слово this, используя apply. В следующем примере foo будет вызываться с this, равным bar:

function foo() { console.log(this); }

let bar = {};
foo.apply(bar);

Есть ли способ добиться того же эффекта в PHP? Кажется возможным просто создать функцию, ссылающуюся на $this вне класса, но это (неудивительно) обрабатывается как любая неопределенная переменная.

Мне известно о call_user_func_array, но это не позволяет мне назначить $this. Я думаю, что размышления могут быть полезны здесь, но я не уверен, как.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Используя выводы из других ответов и комментариев, я придумал реализацию apply в PHP:

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

Не уверен, насколько это полезно. Однако это можно сделать. Обратите внимание, что это работает, только если $new_this является объектом, а не, например, строка или число.

0 голосов
/ 30 октября 2018

Как вы могли прочитать в комментариях, в PHP $this относится к контексту объекта, который может отличаться от контекста JavaScript.

Однако, говоря о области действия, вы можете работать с замыканиями, которые содержат область объекта. Область действия, которая находится внутри $ этой переменной, может быть изменена с помощью Closure::bindTo или Closure::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 instance.

Изменяя область действия, мы можем получить другой результат, в то время как мы получаем доступ к той же переменной из другого экземпляра:

$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

...