2011-07-01 142 views
10

顯然$ pid超出了範圍。該功能不應該「關閉」嗎?我相當確定這是JavaScript中的閉包工作方式。PHP關閉範圍問題

根據一些文章php closures are broken,所以我不能訪問這個

那麼如何從這個閉包函數中訪問$ pid

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); 

編輯我周圍有得到與使用:$col->parser = function($row) use($pid)。不過我覺得這很醜陋。

+4

這不是醜,是封閉在PHP中是如何工作的 – zerkms

+0

這就是它如何在PHP中如此.. – tradyblix

+0

這是一種醜陋的語言,但我堅持下去。 :( – Keyo

回答

25

你需要指定哪些變量應該以這種方式被關閉:

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

如果這個閉包保存在一個變量中,然後傳遞給其他$ pid不存在的範圍,將pid以某種方式封裝在閉包中,或者不可訪問? –

+0

@Josh Nankin:實際上'use($ var,...)'是如何在php中實現閉包的,因此如果將匿名函數傳遞給另一個變量作用域 - '$ pid'變量將包含最後一個定義的值 – zerkms

+1

這個「使用」這個東西是否感覺很奇怪,還是僅僅是我?在使用其他語言的閉包之後,我無法克服它。:/ –

0

可以使用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

我覺得PHP在變量的範圍上非常一致。規則是,如果變量在函數之外定義,則必須明確指定它。對於詞彙範圍,使用'使用',因爲使用全局'全局'。

例如,你不能也直接使用全局變量:

$n = 5; 

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

您必須使用global關鍵字:

$n = 5; 

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