探究PHP中is_callable()與method_exists()函數

來源:互聯網
上載者:User
在很多產品應用中,我們經常能夠看到以下這種用法,它用來檢查一個對象裡的方法是否存在。

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

這段代碼的目的比較容易理解,有一個對象為$object,我們想知道它是否有一個方法為SomeMethod,如果有,就調用此方法。

這個代碼看起來正確,而且在大部分的時候運行也會正常。但是如果這個$object對象的方法對於當前的運行環境是不可見的,程式還能正常運行嗎?正如這個函數名方法存在一樣,只是對我們提供的類或對象檢查是否有我們所期望的方法,如果有,就返回TRUE,如果沒有,就返回FALSE,這裡並沒有考慮可見度的問題。所以,當你恰好判斷一個私人或者受保護的方法時,你能夠得到一個正確的返回,但是執行的時候,會得到一個“Fatal Error”錯誤警告。

上面這段代碼的真正意圖應該理解為:對於提供的類或者對象,我們能否在當前的範圍中調用它的SomeMethod方法。而這正是is_callable()函數存在的目的。is_callable()函數接收一個回調參數,可以指定一個函數名稱或者一個包含方法名和對象的數組,如果在當前範圍中可以執行,就返回TRUE。

<?php    if (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)

在很多產品應用中,我們經常能夠看到以下這種用法,它用來檢查一個對象裡的方法是否存在。

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

這段代碼的目的比較容易理解,有一個對象為$object,我們想知道它是否有一個方法為SomeMethod,如果有,就調用此方法。

這個代碼看起來正確,而且在大部分的時候運行也會正常。但是如果這個$object對象的方法對於當前的運行環境是不可見的,程式還能正常運行嗎?正如這個函數名方法存在一樣,只是對我們提供的類或對象檢查是否有我們所期望的方法,如果有,就返回TRUE,如果沒有,就返回FALSE,這裡並沒有考慮可見度的問題。所以,當你恰好判斷一個私人或者受保護的方法時,你能夠得到一個正確的返回,但是執行的時候,會得到一個“Fatal Error”錯誤警告。

上面這段代碼的真正意圖應該理解為:對於提供的類或者對象,我們能否在當前的範圍中調用它的SomeMethod方法。而這正是is_callable()函數存在的目的。is_callable()函數接收一個回調參數,可以指定一個函數名稱或者一個包含方法名和對象的數組,如果在當前範圍中可以執行,就返回TRUE。

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

下面來舉個例子來說明兩者的區別

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.