function_exists 、 method_exists 和 is_callable 的区别

function_exists — Return TRUE if the given function has beendefined 
method_exists  — Checks if the class methodexists
is_callable — Verify that the contents of a variable can becalled as a function

function_exists 比较简单点,就是判断函数有没有被定义。
method_exists 是判断类内的方法存不存在。
is_callable 检测参数是否为合法的可调用结构。
它们的返回值 都是 bool,但是参数不同。
function_exists  只有一个参数:  函数名 $string
method_exists  两个参数 :  $object 类对象或$class类名称, $string 方法名
is_callable   三个参数:  $var  mixed 可以是string array , $syntax_only bool, $callback_name string

如果is_callable的第一个参数是string,那么 和function_exists 相似 ; 如果是数组 则和 method_exists相似,但又有不同:
(1)method_exists不会考虑类方法的定义范围 public 、protected 、private,只要存在就返回true;而 is_callable 会在方法是被 protecte、 private时返回false。
(2)is_callable会去调用__call魔术方法来判断,而method_exists不会。

<?php
class Test {
    public static $count = 0;

    function testing($flag = false) {
        if ($flag) {
            echo "testing - flag is true<br/>";
        } else {
            echo "testing - flag is false<br/>";
        }
    }

    public function __call($name, $args) {
        if(preg_match('/^not([A-Z]\w+)$/', $name, $matches)) {
            $fn_name = strtolower($matches[1]);
            if(method_exists($this, $fn_name)) {
                $args[] = true; // add NOT boolean to args
                return call_user_func_array(array($this, $fn_name), $args);
            }
        }
        die("No method with name: $name<br/>");
    }

    public static function staticTest($flag) {
        ++self::$count;
        echo self::$count . '次调用' . __FUNCTION__;
    }

    private function privateFuncTest( ) {
        echo "private test func is called.<br/>";
    }

    public  function  callPrivateFuncOfOtherClass() {
        $testObj = new Test1();
        if (is_callable(array($testObj, 'testPrivateCall'))) {
            echo "is_callable: the private of other class can be found in this class";
        } else {
            echo "is_callable: the private of other class can no be found in this class!";
        }
    }
}

class Test1 {
    private function testPrivateCall() {
        echo 'private function in Class T1<br/>';
    }
}

function testfunc() {
    echo "testfunc<br/>";
}

if (function_exists('testfunc')) {
    echo 'function_exists: find the func testfunc<br/>';
} else {
    echo 'function_exists: do not find the func testfunc<br/>';
}

if (function_exists('strtotime')) {
    echo 'function_exists: find the system func strtotime<br/>';
} else {
    echo 'function_exists: do not find the system func strtotime<br/>';
}
echo '<br/>';

$t = new Test();
//直接调用testing方法
$t->testing();
//通过__call和call_user_func_array间接调用testing方法
$t->notTesting();
echo '<br/>';

//method_exists通过类名判断testing方法是否存在
if (method_exists('Test','testing')) {
    echo 'method_exists: testing func find in class Test directly calling the func.<br/>';
} else {
    echo "method_exists: testing func not find in class Test directly calling the func!<br/>";
}
//method_exists通过对象判断testing方法是否存在
if (method_exists($t,'testing')) {
    echo 'method_exists: testing func find in Object of class Test directly calling the func.<br/>';
} else {
    echo "method_exists: testing func not find in Object of class Test directly calling the func!<br/>";
}
//method_exists通过类中的__call判断testing方法是否存在,实际存在,但发现不了
if (method_exists('Test', 'notTesting')) {
    echo 'method_exists: notTesting func find in class Test through calling the func __call.<br/>';
} else {
    echo "method_exists: notTesting func not find in class Test through calling the func __call!<br/>";
}
//method_exists通过对象中的__call判断testing方法是否存在,实际存在,但发现不了
if (method_exists($t, 'notTesting')) {
    echo 'method_exists: notTesting func find in object through calling the func __call.<br/>';
} else {
    echo "method_exists: notTesting func not find in object through calling the func __call!<br/>";
}
//method_exists通过对象判断静态方法是否存在,实际存在,但发现不了
if (method_exists($t, 'privateFuncTest')) {
    echo 'method_exists: privateFuncTest func find in object through calling the func __call.<br/>';
} else {
    echo "method_exists: privateFuncTest func not find in object through calling the func __call!<br/>";
}
echo '<br/>';

//is_callable通过对象中的__call和call_user_func_array间接判断testing方法是否存在,能够发现
if ( is_callable(array($t, 'notTesting')) ) {
    echo "is_callable: notTesting func find in object through calling the func __call.<br/>";
} else {
    echo "is_callable: notTesting func not find in object through calling the func __call!<br/>";
}

//is_callable通过对象判断静态方法staticTest是否存在,能够发现
if ( is_callable(array($t, 'staticTest')) ) {
    echo "is_callable: staticTest func find in object.<br/>";
} else {
    echo "is_callable: staticTest func find exist in object!<br/>";
}
//is_callable通过类判断静态方法staticTest是否存在,能够发现
if ( is_callable(array('Test', 'staticTest')) ) {
    echo "is_callable: staticTest func find in class Test.<br/>";
} else {
    echo "is_callable: staticTest func find exist in class Test!<br/>";
}
//is_callable通过对象判断私有方法staticTest是否存在,能够发现
if ( is_callable(array($t, 'privateFuncTest')) ) {
    echo "is_callable: privateFuncTest func find in object.<br/>";
} else {
    echo "is_callable: privateFuncTest func find exist in object!<br/>";
}

//is_callable通过对象判断其他类的私有方法testPrivateCall是否存在,不能够发现
$t->callPrivateFuncOfOtherClass();
?>
运行结果如下图所示:


猜你喜欢

转载自blog.csdn.net/chinawangfei/article/details/54618703
今日推荐