2011-07-01 15 views
10

Wygląda na to, że $ pid jest poza zakresem. Czy nie powinno być "zamknięte" w funkcji? Jestem dość pewny, że na przykład zamykanie działa w javascript.Problem z zakresem zamykania PHP

Według niektórych artykułów php closures are broken, więc nie mogę uzyskać dostępu do tego?

W jaki sposób można uzyskać dostęp do $ pid z tej funkcji zamykania?

class MyClass { 
    static function getHdvdsCol($pid) { 
    $col = new PointColumn(); 
    $col->key = $pid; 
    $col->parser = function($row) { 
     print $pid; // Undefined variable: pid 
    }; 
    return $col; 
    } 
} 

$func = MyClass::getHdvdsCol(45); 
call_user_func($func, $row); 

Edit Dostałem wokół niego z użytkowania: $col->parser = function($row) use($pid). Jednak czuję, że to jest brzydkie.

+4

Nie jest brzydki, to w jaki sposób zamknięcia pracować w php – zerkms

+0

tak to jest w php, więc .. – tradyblix

+0

To brzydki język, ale utknąłem z tym. :( – Keyo

Odpowiedz

25

Musisz określić, które zmienne powinny być zamknięte w ten sposób:

function($row) use ($pid) { ... } 
+0

Jeśli to zamknięcie jest zapisane w zmiennej, a następnie przekazywane do innego zakresu, w którym $ pid nie istnieje , czy pid będzie zawijany w zamknięciu, czy nie będzie dostępny? –

+0

@Josh Nankin: faktycznie 'use ($ var, ...)' jest jak zaimplementowane są zamknięcia w php. Więc jeśli przekazujesz anonimową funkcję do innego zakresu zmiennych - zmienna '$ pid' będzie zawierała ostatnią zdefiniowaną wartość: – zerkms

+1

Czy to" wykorzystanie "jest dziwne, czy może to tylko ja? Nie mogę się z tym pogodzić po użyciu zamknięć w innych językach:/ –

0

Można użyć metody BindTo.

class MyClass { 
    static function getHdvdsCol($pid) { 
    $col = new PointColumn(); 
    $col->key = $pid; 
    $parser = function($row) { 
     print $this->key; 
    }; 
    $col->parser = $parser->bindTo($parser, $parser); 
    return $col; 
    } 
} 

$func = MyClass::getHdvdsCol(45); 
call_user_func($func, $row); 
-4

Uważam, że PHP jest bardzo spójne w określaniu zakresów zmiennych. Reguła jest taka, że ​​jeśli zmienna jest zdefiniowana poza funkcją, musisz ją jawnie określić. W przypadku zakresu leksykalnego stosuje się "use", w przypadku globalnych "global".

Na przykład, nie można też użyć zmiennej globalnej bezpośrednio:

$n = 5; 

function f() 
{ 
    echo $n; // Undefined variable 
} 

należy użyć globalnego kluczowe:

$n = 5; 

function f() 
{ 
    global $n; 
    echo $n; 
}