Почему именно передача замыкания из одного класса в другой и вызов его из второго класса выполняет код из первого класса?

Довольно сложно придумать название для этого вопроса, но в основном вот код:

<?php

class Sub {
protected $closure;

public function setClosure($closure) {
$this->closure = $closure;
}

public function callClosure() {
$this->closure->__invoke();
}

protected function outcome() {
echo 'calling from sub';
}
}

class Main {
public function __construct() {
$this->sub = new Sub();
}

public function start() {
$this->sub->setClosure(function() {
$this->outcome();
});

$this->sub->callClosure();
}

protected function outcome() {
echo 'calling from main';
}
}

$main = new Main();
$main->start();

Результатом этого является calling from main, Однако это именно то, чего я хочу, так как я буду иметь дело с этим поведением, и я не до конца понимаю, почему это работает так, я хотел бы получить некоторые пояснения.

Перед написанием кода я ожидал, что он вызовет outcome метод из Sub класс, а не из Main учебный класс. Использует ли закрытие $this из области, из которой это было определено? Что делать, если по какой-то причине я хочу использовать $this из области его вызова?

2

Решение

Работает правильно и согласно PHP анонимные функции ручной, потому что

Родительская область действия замыкания — это функция, в которой замыкание было
объявлен (не обязательно функция, из которой он был вызван)

В php эта анонимная функция реализована как Закрытие класса.
И как уже Марк Бейкер сказал, когда вы создаете свое закрытие внутри вашего Main класс, вы автоматически получаете этот связанный объект и эту область видимости.

«Связанный объект» определяет значение $, которое будет иметь
Тело функции и «область видимости» представляет класс, который
определяет, какие частные и защищенные члены анонимной функции
будет иметь доступ. А именно, члены, которые будут видны
так же, как если бы анонимная функция была методом данного класса
в качестве значения параметра newscope.

В вашем случае этот класс Main не Sub

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]