雖然你不能,如果區分方法是私人的或受保護的,您可以測試公開與不使用is_callable
的外部方法。我與「meze」的答案進行了比較。
所以:
function testIfCallable($object, $method) {
return is_callable(array($object, $method));
}
function testIfCallable2($object, $method) {
if (method_exists($object, $method))
{
$reflection = new ReflectionMethod($object, $method);
return $reflection->isPublic();
}
return false;
}
class Test {
private function privateMethod() {
}
protected function protectedMethod() {
}
public function publicMethod() {
}
public function testAccessibility() {
if (testIfCallable($this, 'privateMethod')) echo "YYY<br>"; else echo 'NNN<br>';
if (testIfCallable($this, 'protectedMethod')) echo "YYY<br>"; else echo 'NNN<br>';
if (testIfCallable($this, 'publicMethod')) echo "YYY<br>"; else echo 'NNN<br>';
}
public function testAccessibility2() {
if (testIfCallable2($this, 'privateMethod')) echo "YYY<br>"; else echo 'NNN<br>';
if (testIfCallable2($this, 'protectedMethod')) echo "YYY<br>"; else echo 'NNN<br>';
if (testIfCallable2($this, 'publicMethod')) echo "YYY<br>"; else echo 'NNN<br>';
}
public function testSpeedAccessibility() {
return $results = [
testIfCallable($this, 'privateMethod'),
testIfCallable($this, 'protectedMethod'),
testIfCallable($this, 'publicMethod')
];
}
public function testSpeedAccesibility2() {
return $results = [
testIfCallable2($this, 'privateMethod'),
testIfCallable2($this, 'protectedMethod'),
testIfCallable2($this, 'publicMethod')
];
}
}
方法testIfCallable
應包括在一個共同的類或你有你自己的工具包,因爲不推薦使用全局方法類似。
我使用這個結合魔術方法__get
和__set
來確保存在公共的「get/set」方法。
測試:
//Test functionality
$t = new Test();
$t->testAccessibility();
$t->testAccessibility2();
//Test speed
$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
$t->testSpeedAccessibility();
}
echo "Is Callable way: " . (microtime(true) - $start) . "ms<br>";
$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
$t->testSpeedAccesibility2();
}
echo "Reflection way: " . (microtime(true) - $start) . "ms<br>";
輸出:
NNN
NNN
YYY
NNN
NNN
YYY
Is Callable way: 0.23506498336792ms
Reflection way: 0.45829010009766ms
最後的想法
如果你需要所有的知名度可能性之間進行測試,你只能去的方法是使用testIfCallable2
,所以「meze」的答案。否則,我的方式快兩倍左右。由於你的問題只是在公衆之間,你可以從中受益。說這個,如果你不經常使用它,差異就不明顯了。
我是爲這一個,但你來到我面前:) – 2010-11-12 01:45:40
真棒,謝謝:) – 2010-11-12 02:01:53