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

<?phpif (method_exists($object, 'SomeMethod')) {       $object->SomeMethod($this, TRUE); }?

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

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

上面这段代码的真正意图应该理解为:对于提供的类或者对象,我们能否在当前的作用域中调用它的SomeMethod方法。而这正是is_callable()函数存在的目的。is_callable()函数接收一个回调参数,可以指定一个函数名称或者一个包含方法名和对象的数组,如果在当前作用域中可以执行,就返回TRUE。

<?phpif (is_callable(array($object, 'SomeMethod'))) {      $object->SomeMethod($this, TRUE); }?>

下面来举个例子来说明两者的区别

<?phpclass 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('-', 10);    echo '<br />';}

执行上面的脚本后,我们会清晰地看到两个函数间的差别。

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

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

<?phpclass 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)

1.jpg

推荐:PHP视频教程

更多相关文章

  1. 浅谈PHP面向对象的继承
  2. API常用签名验证方法(PHP实现)
  3. Mac电脑设置hosts的方法(图文步骤)
  4. php删除文件的方法
  5. php下载网络图片常用的三个方法总结
  6. php时间戳转换成时间的方法
  7. PHP中的面向对象实践-基本实践案例
  8. PHP面向对象到底是啥?十分钟通俗易懂图文教程
  9. PHP中的面向对象之构造函数详解

随机推荐

  1. 网易云音乐评论爬取。
  2. Javascript的对象拷贝[每日前端夜话0x53]
  3. 使用ESLint + Prettier简化代码 Review
  4. Edge 拥抱 Chromium 对前端工程师意味着
  5. 数据整合与数据清洗。
  6. 跟繁琐的命令行说拜拜!Gerapy分布式爬虫管
  7. TensorFlow layers模块用法
  8. Mybatis if, set, where 动态sql和sql片
  9. 99%的人都不知道的pandas骚操作(一)
  10. TensorFlow RNN Cell源码解析