前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >method_exists VS is_callable

method_exists VS is_callable

作者头像
大江小浪
发布2018-07-25 10:06:20
3390
发布2018-07-25 10:06:20
举报
文章被收录于专栏:小狼的世界小狼的世界

今天看到一篇介绍,关于 method_exist 的,我觉得自己也有必要记录一下。

在很多应用中,我们经常能够看到下面的这种用法。用来检查一个对象的一个方法是否存在:

代码语言:javascript
复制
if (method_exists($object, 'SomeMethod')) {   
   $object->SomeMethod($this, TRUE); 
}

这段代码的目的非常容易理解,有一个对象为 $object,我们想知道他是否有一个方法为 SomeMethod 。如果有,就调用这个方法。

这个代码看起来很正确,而且在大部分的时候,工作的也非常好。但是如果这个 $object 对象的方法对于当前的运行环境是不可见的,程序还能正常运行吗?method_exists 正如这个函数名一样,只是对我们提供的类或对象检查是否有我们所期望的方法,如果有,就返回TRUE,如果没有,就返回FALSE,这里并没有考虑可见性的问题。所以,如果你恰好判断一个私有或者受保护的方法时,你能够得到一个正确的返回,但是执行的时候,会得到一个 “Fatal Error”。

正确的做法

其实上面一段代码的真正意图应该理解为:对于提供的类或者对象,我们能否在当前的作用域中调用他的 SomeMethod 方法。而这正是 is_callable() 存在的目的。

如何来做

is_callable 接收一个回调参数,可以指定一个函数名称或者一个包含方法名和对象的数组,如果在当前作用域中可以执行,就返回TRUE,如果不能就FALSE。

代码语言:javascript
复制
if (is_callable(array($object, 'SomeMethod'))) {
   $object->SomeMethod($this, TRUE); 
}

下面是一个例子,用来说明 method_exists 和 is_callable 的区别:

代码语言:javascript
复制
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){
    var_dump($callback);
    var_dump(method_exists($callback[0], $callback[1]));
    var_dump(is_callable($callback));
    echo str_repeat('-', 40);
    echo '<br />';
}

执行这个例子,我们就能购清晰的看到两个函数间的差别。

补充

is_callable 还有其他的用法,例如不检查所提供的类或方法,只是检查函数或方法的语法是否正确。像 method_exists一样,is_callable 可以触发类的自动加载。

如果一个对象有魔术方法 __call,在进行方法判断的时候 method_exists 会返回FALSE , 而is_callable 会返回TRUE。

如下例:

代码语言:javascript
复制
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 />';

参考资料:

1、is_callable

2、method_exists

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-08-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档