Есть ли у PHP лексическая область действия в анонимных функциях / замыканиях?

Я использую PHP 5.4 и задаюсь вопросом, есть ли у анонимных функций, которые я делаю, лексическая область видимости?

Т.е. если у меня есть метод контроллера:

protected function _pre() {
    $this->require = new Access_Factory(function($url) {
        $this->redirect($url);
    });
}

Когда Access Factory вызывает функцию, которую она передала, будет ли $ this ссылаться на контроллер, где он был определен?

2 ответа

Решение

Анонимные функции не используют лексическую область видимости, но $this является особым случаем и будет автоматически доступен внутри функции начиная с 5.4.0. Ваш код должен работать должным образом, но он не будет переносимым на более старые версии PHP.


Следующее не будет работать:

protected function _pre() {
    $methodScopeVariable = 'whatever';
    $this->require = new Access_Factory(function($url) {
        echo $methodScopeVariable;
    });
}

Вместо этого, если вы хотите ввести переменные в область действия замыкания, вы можете использовать use ключевое слово. Следующее будет работать:

protected function _pre() {
    $methodScopeVariable = 'whatever';
    $this->require = new Access_Factory(function($url) use ($methodScopeVariable) {
        echo $methodScopeVariable;
    });
}

В 5.3.x вы можете получить доступ к $this со следующим обходным путем:

protected function _pre() {
    $controller = $this;
    $this->require = new Access_Factory(function($url) use ($controller) {
        $controller->redirect($url);
    });
}

Смотрите этот вопрос и его ответы для более подробной информации.

Короче говоря, нет, но вы можете получить доступ к открытым методам и функциям, передав их:

$that = $this;
$this->require = new Access_Factory(function($url) use ($that) {
    $that->redirect($url);
});

редактировать: как Мэтт правильно указал на поддержку $this в замыканиях началось с PHP 5.4

Другие вопросы по тегам