回调函数与PHP实例
1 什么是回調(diào)
? ? ? ?軟件模塊之間總是存在著一定的接口,從調(diào)用方式上,可以把他們分為三類:同步調(diào)用、回調(diào)和異步調(diào)用。同步調(diào)用是一種阻塞式調(diào)用,調(diào)用方要等待對方執(zhí)行完畢才返回,它是一種單向調(diào)用;回調(diào)是一種雙向調(diào)用模式,也就是說,被調(diào)用方在接口被調(diào)用時(shí)也會調(diào)用對方的接口;異步調(diào)用是一種類似消息或事件的機(jī)制,不過它的調(diào)用方向剛好相反,接口的服務(wù)在收到某種訊息或發(fā)生某種事件時(shí),會主動通知客戶方(即調(diào)用客戶方的接口)。回調(diào)和異步調(diào)用的關(guān)系非常緊密,通常我們使用回調(diào)來實(shí)現(xiàn)異步消息的注冊,通過異步調(diào)用來實(shí)現(xiàn)消息的通知。同步調(diào)用是三者當(dāng)中最簡單的,而回調(diào)又常常是異步調(diào)用的基礎(chǔ),因此,下面我們著重討論回調(diào)機(jī)制在不同軟件架構(gòu)中的實(shí)現(xiàn)。
? ? ? 對于不同類型的語言(如結(jié)構(gòu)化語言和對象語言)、平臺(Win32、JDK)或構(gòu)架(CORBA、DCOM、WebService),客戶和服務(wù)的交互除了同步方式以外,都需要具備一定的異步通知機(jī)制,讓服務(wù)方(或接口提供方)在某些情況下能夠主動通知客戶,而回調(diào)是實(shí)現(xiàn)異步的一個(gè)最簡捷的途徑。對于一般的結(jié)構(gòu)化語言,可以通過回調(diào)函數(shù)來實(shí)現(xiàn)回調(diào)。回調(diào)函數(shù)也是一個(gè)函數(shù)或過程,不過它是一個(gè)由調(diào)用方自己實(shí)現(xiàn),供被調(diào)用方使用的特殊函數(shù)。
在面向?qū)ο蟮恼Z言中,回調(diào)則是通過接口或抽象類來實(shí)現(xiàn)的,我們把實(shí)現(xiàn)這種接口的類成為回調(diào)類,回調(diào)類的對象成為回調(diào)對象。對于象C++或Object Pascal這些兼容了過程特性的對象語言,不僅提供了回調(diào)對象、回調(diào)方法等特性,也能兼容過程語言的回調(diào)函數(shù)機(jī)制。Windows平臺的消息機(jī)制也可以看作是回調(diào)的一種應(yīng)用,我們通過系統(tǒng)提供的接口注冊消息處理函數(shù)(即回調(diào)函數(shù)),從而實(shí)現(xiàn)接收、處理消息的目的。由于Windows平臺的API是用C語言來構(gòu)建的,我們可以認(rèn)為它也是回調(diào)函數(shù)的一個(gè)特例。對于分布式組件代理體系CORBA,異步處理有多種方式,如回調(diào)、事件服務(wù)、通知服務(wù)等。事件服務(wù)和通知服務(wù)是CORBA用來處理異步消息的標(biāo)準(zhǔn)服務(wù),他們主要負(fù)責(zé)消息的處理、派發(fā)、維護(hù)等工作。對一些簡單的異步處理過程,我們可以通過回調(diào)機(jī)制來實(shí)現(xiàn)。
2 PHP的回調(diào)函數(shù)的實(shí)現(xiàn)方法
2.1 全局函數(shù)的回調(diào)
? ? ?這里的全局函數(shù)的意思,是直接使用function定義的函數(shù),它不包含在任何對象或類之中。請看下面的例子
function fnCallBack( $msg1 , $msg2 )
{
??? echo 'msg1:'.$msg1;
? ? echo "<br />\n";
? ? echo 'msg2:'.$msg2;
}
?
$fnName = "fnCallBack"; //方法名
$params = array( 'hello' , 'world' );//傳給參數(shù)的值
call_user_func_array( $fnName , $params );
結(jié)果:
代碼說明:
? ? 這里使用了PHP內(nèi)置的函數(shù)call_user_func_array來進(jìn)行調(diào)用。call_user_func_array有兩個(gè)參數(shù),第1個(gè)參數(shù)是一個(gè)字符串,表示要調(diào)用的函數(shù)名,第2個(gè)參數(shù)是一個(gè)數(shù)組,表示參數(shù)列表,按照順序依次會傳遞給要調(diào)用的函數(shù)。
2.2 類的靜態(tài)方法的回調(diào)
? ? ?如果我們要回調(diào)的方法,是一個(gè)類的靜態(tài)方法,那怎么辦呢?我們依然可以利用PHP內(nèi)置的call_user_func_array方法來進(jìn)行調(diào)用,請看示例:
示例代碼:
class MyClass
{
? ? public static function fnCallBack( $msg1 , $msg2 )
? ??{
? ? ? ? echo 'msg1:'.$msg1;
? ? ??? echo "<br />\n";
? ? ??? echo 'msg2:'.$msg2;
? ? }
}
$className = 'MyClass'; //類名
$fnName = "fnCallBack";//類中的方法名
$params = array( 'hello' , 'world' );//傳給參數(shù)的值
call_user_func_array( array( $className , $fnName ) , $params );
?
結(jié)果:
代碼說明:
? ??這段代碼和第1種方法的代碼很相似,我們將類名(MyClass)也作為call_user_func_array的第1個(gè)參數(shù)傳遞進(jìn)去,就可以實(shí)現(xiàn)類的靜態(tài)方法的回調(diào)了。注意,這時(shí)call_user_func_array的第1個(gè)參數(shù)是一個(gè)數(shù)組了,數(shù)組的第1個(gè)元素是類名,第二個(gè)元素是要調(diào)用的函數(shù)名
如果我用這種方法調(diào)用一個(gè)類的非靜態(tài)方法(也就是把static去掉),會出現(xiàn)什么結(jié)果呢?請看下面代碼
class MyClass
{
??? public function fnCallBack( $msg1 , $msg2 )
? ? {
? ??? ? echo 'msg1:'.$msg1;
? ? ? ? echo "<br />\n";
? ? ? ? echo 'msg2:'.$msg2;
??? }
}
$className = 'MyClass';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
最終運(yùn)行的結(jié)果跟原來一樣
2.3 對象的方法的回調(diào)
? 我先用最原始的字符串形式的調(diào)用方法嘗試了一下,如下所示:
class MyClass
{
? ? private $name = 'abc';
? ? public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
? ??{
? ? ??? echo 'object name:'.$this->name;
? ? ??? echo "<br />\n";
? ? ??? echo 'msg1:'.$msg1;
? ? ? ? echo "<br />\n";
? ? ? ? echo 'msg2:'.$msg2;
? ? }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
$myobj->$fnName();
結(jié)果:
調(diào)用是成功了,不過如何把參數(shù)params傳給這個(gè)方法呢,如果把params直接傳進(jìn)去,那么它會作為1個(gè)參數(shù),怎么把params拆開來傳進(jìn)去呢?查了下PHP手冊,找到了create_function函數(shù),這個(gè)方法可以用字符串來創(chuàng)建一個(gè)匿名函數(shù),好,有思路了,可以創(chuàng)建一個(gè)匿名的函數(shù),在這個(gè)匿名函數(shù)中,調(diào)用我們的回調(diào)函數(shù),并把參數(shù)傳進(jìn)去。
我先手動創(chuàng)建一個(gè)匿名函數(shù)anonymous,在這個(gè)函數(shù)中,用前面試出來的方法調(diào)用回調(diào)函數(shù),如下所示:
class MyClass
{
? ? private $name = 'abc';
? ? public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
? ??{
? ? ? ??echo 'object name:'.$this->name;
? ? ??? ?echo "<br />\n";
? ? ? ? echo 'msg1:'.$msg1;
? ? ? ??echo "<br />\n";
? ? ? ? echo 'msg2:'.$msg2;
? ? }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
//匿名函數(shù)的構(gòu)建
function anonymous()
{
??? global $myobj;
??? global $fnName;
? ? global $params;
? ? $myobj->$fnName( $params[0] , $params[1] );
}
anonymous();
成功了。效果如下:
轉(zhuǎn)載于:https://www.cnblogs.com/zw874827903/p/6921459.html
總結(jié)
以上是生活随笔為你收集整理的回调函数与PHP实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (数字IC)低功耗设计入门(六)——门级
- 下一篇: Docker + Jenkins 快速打