2011-08-18 53 views
20

一個有效的封閉使用以下功能:確定,如果一個變量是在PHP

function is_closure($t) { return (!is_string($t) && is_callable($t)); }

可這回真爲別的,就不是一個匿名閉包功能?如果是這樣,如果一個變量是閉包,那麼確定的正確方法是什麼?

非常感謝

+2

如果實現['__invoke'](http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.invoke),對象也可以調用。 – mario

回答

40

最確定的方式來檢查,如果回調是一個實際的閉包:

function is_closure($t) { 
    return is_object($t) && ($t instanceof Closure); 
} 

所有的匿名函數中表示爲PHP類型Closure的對象。 (回到上面的評論,碰巧實現了__invoke()方法。)

+4

讓我絆倒了一兩分鐘的東西......如果你的代碼是命名空間的,確保轉義\ Closure返回到全局命名空間。 – Jim

+7

您不需要執行'is_object($ t)',爲非對象執行'instanceof'將始終返回false。 –

13

我認爲你可以使用instanceof Closure,儘管manual聲明不應該依賴這個。我想它現在可以運行

匿名函數當前使用Closure類實現。這是一個實現細節,不應該依賴。

更新 的封閉manual page已更新了該公司的指導。看來現在可以依靠這種行爲。

在PHP 5.3中實現的匿名函數產生這種類型的對象。這個事實過去被認爲是一個實現細節,但現在可以依賴它了。

+0

@mario打敗了我,但我會在這裏留下這些額外的信息(除非馬里奧想把它與他的答案合併) – Phil

2

php.net建議使用反射弄清楚如果變量中包含一個有效的封閉與否

我用這個小幫手

function isClosure($suspected_closure) { 
    $reflection = new ReflectionFunction($suspected_closure); 

    return (bool) $reflection->isClosure(); 
} 
0

如果您收到有關該錯誤的錯誤ReflectionFunction,請在課前使用反斜槓

// Closure 
$closure = function() {}; 
$reflection = new \ReflectionFunction($closure); 
// checkout if it is a closure 
$test->isTrue($reflection->isClosure()); 
相關問題