2013-05-03 10 views
6

Używam PHP 5.4 i zastanawiam się, czy anonimowe funkcje, które robię, mają zakres leksykalny?Czy PHP ma zakres leksykalny w anonimowych funkcjach/zamknięciach?

tj. Jeśli mam metody kontrolera:

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

Kiedy fabryka Dostęp wywołuje funkcję został przekazany, będzie $ to odnosi się do kontrolera, gdzie został zdefiniowany?

Odpowiedz

6

Funkcje anonimowe nie używają zakresu leksykalnego, ale $this is a special case and will automatically be available inside the function as of 5.4.0. Twój kod powinien działać zgodnie z oczekiwaniami, ale nie będzie przenośny dla starszych wersji PHP.


Następujące będzie nie praca:

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

Zamiast tego, jeśli chcesz wprowadzić zmienne do zakresu zamknięcia jest, można użyć słowa kluczowego use. Poniższy będzie praca:

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

W 5.3.x, można uzyskać dostęp do $this z następującym obejścia:

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

Zobacz this question and its answers więcej szczegółów.

+0

Ach, dobrze jest wiedzieć, że jest inaczej w PHP5.4 (który jeszcze nie dotarł do moich pakietów stabilnych w Debianie) może być konieczne ręczne zainstalowanie). – Wrikken

+0

Czy potrzebuję "użycia ($ this)" lub czy 5.4 automatycznie daje ci dostęp do $ this? – Charles

+0

5.4.0+ automatycznie wiąże '$ this'. Sprawdź [to krótkie wideo] (http://youtu.be/-Ph7X6Y6n6g), wyjaśniając to. –

1

W skrócie, nie, ale można uzyskać dostęp publicznym Metody & funkcje poprzez przepuszczenie go:

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

edit: jak słusznie zauważył Matt support for $this in closures started with PHP 5.4

Powiązane problemy