2017-04-10 60 views
1

我正在嘗試反思並試圖理解閉包。 這裏是我的代碼(PHP的版本是5.6):爲什麼__invoke不會顯示在ReflectionClass :: getMethods結果中,但是ReflectionClass :: hasMethod(「__ invoke」)返回true?

function closureWithState ($name) { 
    return function() use ($name) { // 'use' keyword attaches the closure state 
     return strToUpper($name); 
    }; 
} 

$closure = closureWithState('Foo'); 

$reflector = new ReflectionClass($closure); 
$methods = $reflector->getMethods(); 
foreach ($methods as $method) { 
    echo $method->getName() . PHP_EOL; 
} 

echo "Result of hasMethod for __invoke: " .$reflector->hasMethod("__invoke") . PHP_EOL; 

和我的輸出是

__construct 
bind 
bindTo 
Result of hasMethod for __invoke: 1 

如此看來,getMethods回報的方法__construct綁定bindTo但不是__invoke。但是當我測試hasMethod("__invoke")時,它返回true

這裏發生了什麼?

+0

閉包是否有一個真正的'__construct'?或者可能它沒有被顯示,因爲'__invoke'主要是爲類作爲一個函數。所以也許多數民衆贊成的原因是不expli。顯示,但功能默認情況下給出。也許(第3個)這就是爲什麼hasMethod給出真正的原因(expli。要求'__invoke'),但getMethod忽略它。如果這樣做沒有意義,那麼寫一個關於php.net的bug報告 – JustOnUnderMillions

+0

我認爲用反射你不會得到魔術方法列表。嘗試在您定義魔術方法的類中使用反射。 – Andreas

+0

也許你是對的,但反射顯示__construct? – Monkeybrain

回答

0

你應該在這裏使用ReflectionObject代替ReflectionClass

<?php 

$closure = function() {}; 

$reflection = new \ReflectionObject($closure); 

$methodNames = array_map(function (\ReflectionMethod $method) { 
    return $method->getName(); 
}, $reflection->getMethods()); 

var_dump($methodNames); 

僅供參考,請參閱:

有關示例,請參見:

相關問題