php自訂函數的回呼函數用法詳解

伊谢尔伦
發布: 2023-03-11 13:42:01
原創
2570 人瀏覽過

 最近在開發一個PHP系統,為了提高系統的擴充性,我想在系統中加入類似Javascript事件處理機制,例如:我想在一篇新聞被加入以後,我想記錄日誌,用類似Javascript的程式碼,應該是這樣寫的:

function fnCallBack( $news )
{
     //将$news的信息记录到日志中
    writeLog( $news->getTitle().' has been added successfully!');
}
$newsEventManager->addEventListener( 'add' , fnCallBack );
登入後複製

  其中,fnCallBack函數是回呼函數,addEventListener表示監聽newsEventManager的add事件。當一篇news被add以後,系統就會呼叫fnCallBack函數,從而完成writeLog的動作。

    但是,PHP中的函數傳遞方法和Javascript有很大的不同。在Javascript中,函數也是對象,它可以很方便的當作參數傳遞,但是PHP不行。

$newsEventManager->addEventListener( 'add' , fnCallBack );
登入後複製

上面這行程式碼中的fnCallBack,看起來好像是那個函數的句柄,但實質上它是一個字串,並不是我們所要的函數。

為了實作我們的事件模型,有必要研究一下PHP的回呼函數的實作方法。

1. 全域函數的回呼

這裡的全域函數的意思,是直接使用function定義的函數,它不包含在任何物件或類別之中。請看下面的範例

 範例程式碼:

function fnCallBack( $msg1 , $msg2 )
{
    echo 'msg1:'.$msg1;
    echo "<br />\n";
    echo &#39;msg2:&#39;.$msg2;
}
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
call_user_func_array( $fnName , $params );
登入後複製

程式碼說明:
    這裡使用了PHP內建的函數call_user_func_array來進行呼叫。 call_user_func_array有兩個參數,第1個參數是一個字串,表示要呼叫的函數名,第2個參數是數組,表示參數列表,依照順序依序會傳遞給要呼叫的函數。

2. 類別的靜態方法的回呼

如果我們要回呼的方法,是一個類別的靜態方法,那該怎麼辦呢?我們依然可以利用PHP內建的call_user_func_array方法來進行調用,請看範例:
範例程式碼:

class MyClass
{
    public static function fnCallBack( $msg1 , $msg2 )
    {
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$className = &#39;MyClass&#39;;
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
call_user_func_array( array( $className , $fnName ) , $params );
登入後複製

程式碼說明:  
    這段程式碼和第1種方法的程式碼很相似,我們將類別名稱(MyClass)也當作call_user_func_array的第1個參數傳遞進去,就可以實作類別的靜態方法的回呼了。注意,這時call_user_func_array的第1個參數是一個陣列了,陣列的第1個元素是類別名,第二個元素是要呼叫的函數名

3. 物件的方法的回呼
先用最原始的字串形式的呼叫方法嘗試了一下,如下所示:

class MyClass
{
    private $name = &#39;abc&#39;;
    public function fnCallBack( $msg1 = &#39;default msg1&#39; , $msg2 = &#39;default msg2&#39; )
    {
        echo &#39;object name:&#39;.$this->name;
        echo "<br />\n";
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
$myobj->$fnName();
登入後複製

呼叫是成功了,不過如何把參數params傳給這個方法呢,如果把params直接傳進去,那麼它會當作1個參數,要怎麼把params拆開來傳進去呢?
查了一下PHP手冊,找到了create_function函數,這個方法可以用字串來創建一個匿名函數,好,有思路了,可以創建一個匿名的函數,在這個匿名函數中,呼叫我們的回呼函數,並把參數傳進去。

先手動建立一個匿名函數anonymous,在這個函數中,用前面試出來的方法呼叫回呼函數,如下所示:

class MyClass
{
    private $name = &#39;abc&#39;;
    public function fnCallBack( $msg1 = &#39;default msg1&#39; , $msg2 = &#39;default msg2&#39; )
    {
        echo &#39;object name:&#39;.$this->name;
        echo "<br />\n";
        echo &#39;msg1:&#39;.$msg1;
        echo "<br />\n";
        echo &#39;msg2:&#39;.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( &#39;hello&#39; , &#39;world&#39; );
function anonymous()
{
    global $myobj;
    global $fnName;
    global $params;
    $myobj->$fnName( $params[0] , $params[1] );
}
anonymous();
登入後複製

然後,我用create_function來創建這個匿名函數,同時,程式碼中的params[0],params[1]應該是動態產生的,程式碼如下:

$strParams = &#39;&#39;;
$strCode = &#39;global $myobj;global $fnName;global $params;$myobj->$fnName(&#39;;
for ( $i = 0 ; $i < count( $params ) ; $i ++ )
{
    $strParams .= ( &#39;$params[&#39;.$i.&#39;]&#39; );
    if ( $i != count( $params )-1 )
    {
        $strParams .= &#39;,&#39;;
    }
}
$strCode = $strCode.$strParams.");";
$anonymous = create_function( &#39;&#39; , $strCode);
$anonymous();
登入後複製

這段程式碼可以定義一個匿名函數,並保存在$ anonymous變數中,最後呼叫這個$anonymous,實作了方法的回呼。

以上是php自訂函數的回呼函數用法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板