购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.16 is_callable()与method_exists()函数

在很多产品应用中,我们经常能够看到以下这种用法,它用来检查一个对象里的方法是否存在。如代码清单1-24所示:

代码清单1-24 检查一个对象中的方法是否存在


<php
if method_exists$object 'SomeMethod')) {   
    $object->SomeMethod$this TRUE); 
}>

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

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

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

is_callable()函数接收一个回调参数,可以指定一个函数名称或者一个包含方法名和对象的数组,如果在当前作用域中可以执行,就返回TRUE。如代码清单1-25所示:

代码清单1-25 使用is_callable()函数


<php
if is_callablearray$object 'SomeMethod'))) {
      $object->SomeMethod$this TRUE); 
}>

下面我们举一个例子,来说明method_exists()和is_callable()函数的区别。如代码清单1-26所示:

代码清单1-26 method_exits()和is_callable()函数的区别


<php
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_dumpmethod_exists$callback[0] $callback[1]));
    var_dumpis_callable$callback));
    echostr_repeat'-' 40);
    echo '<br />'
}>

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

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

如果一个对象存在魔术方法_call,在进行方法判断时method_exists()会返回FALSE,而is_callable()会返回TRUE。如代码清单1-27所示:

代码清单1-27 使用__call魔术方法


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_dumpmethod_exists$obj'runtest'));
var_dumpis_callablearray$obj'runtest')));
echo '<br />'
  

下面我们总结一个表格,对比两个函数的详细区别(见表1-3)。

表1-3 method_exists()与is_callable()函数的比较 WODVMg96KNn8Zc51lV56h2hVm1x7BfFO4V/1zcGlUzyeBIfuLdi/8K+LomOTPxHV

点击中间区域
呼出菜单
上一章
目录
下一章
×