我们经常能够看到以下这种用法,它用来检查一个对象里的方法是否存在
<?php
if (method_exists($object, 'SomeMethod')) {
$object->SomeMethod($this, TRUE);
}
?>
不管方法是否可见(private,protected),
method_exists
否会返回 TRUE
如果我们想不可见的返回 FALSE ,就需要使用方法 is_callable
函数接收一个回调参数,可以指定一个函数名称或者一个包含方法名和对象的数组
区别
看例子:
class Foo {
public function PublicMethod(){}
private function PrivateMethod(){}
public static function PublicStaticMethod(){}
private static function PrivateStaticMethod(){}
}
$foo = new Foo();
$callbacks = array(
array($foo, 'PublicMethod'),
array($foo, 'PrivateMethod'),
array($foo, 'PublicStaticMethod'),
array($foo, 'PrivateStaticMethod'),
array('Foo', 'PublicMethod'),
array('Foo', 'PrivateMethod'),
array('Foo', 'PublicStaticMethod'),
array('Foo', 'PrivateStaticMethod'),
);
foreach ($callbacks as $callback){
echo "<pre>";
var_dump($callback);
var_dump(
[
'method_exists' => method_exists($callback[0], $callback[1]),
'is_callable' => is_callable($callback),
]
);
echo str_repeat('-', 30);
echo '<br />';
}
比较
比较内容 | method_exists | is_callable |
---|---|---|
适用范围 | 仅适用类方法 | 适用类方法和全局方法 |
是否有上下文 | 否 | 是,会判断一个函数是否在当前环境中可调用(例如在子类中判断能否调用父类构造函数) |
是否判断权限 | 否 | 是,在类外,判断 private 和 protected 会返回false |
是否调用 call方法 | 否 | 是 |
速度 | 快 | 慢 |
is_callable()
还有其他的用法,例如,不检查所提供的类或方法,只检查函数或方法的语法是否正确。像method_exists()
一样,is_callable()
可以触发类的自动加载。
一个对象存在魔术方法__call,在进行方法判断时method_exists()会返回FALSE,而is_callable()会返回TRUE。
<?php
class MethodTest {
public function __call($name, $arguments){
echo 'Calling object method ' . $name . ' ' .implode(', ', $arguments);
echo '<br />';
}
}
$obj = new MethodTest();
$obj->runtest('in object context');
var_dump(method_exists($obj,'runtest'));
var_dump(is_callable(array($obj,'runtest')));
echo '<br />';
运行结果
Calling object method runtest in object context
bool(false) bool(true)