搜尋
首頁後端開發php教程回调函数的原理及PHP范例

回调函数的原理及PHP实例

背景:在最近的一个开发项目中,用户要先调用服务才能开始进行一系列的查询活动,想了好久,经同事提醒, 用回调函数即可解决该问题。在这里,对PHP下回调函数的原理及实现分别做一下讲解。


1 什么是回调

       软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。

      对于不同类型的语言(如结构化语言和对象语言)、平台(Win32、JDK)或构架(CORBA、DCOM、WebService),客户和服务的交互除了同步方式以外,都需要具备一定的异步通知机制,让服务方(或接口提供方)在某些情况下能够主动通知客户,而回调是实现异步的一个最简捷的途径。对于一般的结构化语言,可以通过回调函数来实现回调。回调函数也是一个函数或过程,不过它是一个由调用方自己实现,供被调用方使用的特殊函数。
在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类成为回调类,回调类的对象成为回调对象。对于象C++或Object Pascal这些兼容了过程特性的对象语言,不仅提供了回调对象、回调方法等特性,也能兼容过程语言的回调函数机制。Windows平台的消息机制也可以看作是回调的一种应用,我们通过系统提供的接口注册消息处理函数(即回调函数),从而实现接收、处理消息的目的。由于Windows平台的API是用C语言来构建的,我们可以认为它也是回调函数的一个特例。对于分布式组件代理体系CORBA,异步处理有多种方式,如回调、事件服务、通知服务等。事件服务和通知服务是CORBA用来处理异步消息的标准服务,他们主要负责消息的处理、派发、维护等工作。对一些简单的异步处理过程,我们可以通过回调机制来实现。

2 PHP的回调函数的实现方法


2.1 全局函数的回调

     这里的全局函数的意思,是直接使用function定义的函数,它不包含在任何对象或类之中。请看下面的例子
function fnCallBack( $msg1 , $msg2 )
{
    echo 'msg1:'.$msg1;
    echo "
\n";
    echo 'msg2:'.$msg2;

}


$fnName = "fnCallBack"; //方法名
$params = array( 'hello' , 'world' );//传给参数的值

call_user_func_array( $fnName , $params );

结果:


代码说明:
    这里使用了PHP内置的函数call_user_func_array来进行调用。call_user_func_array有两个参数,第1个参数是一个字符串,表示要调用的函数名,第2个参数是一个数组,表示参数列表,按照顺序依次会传递给要调用的函数。

2.2 类的静态方法的回调
     如果我们要回调的方法,是一个类的静态方法,那怎么办呢?我们依然可以利用PHP内置的call_user_func_array方法来进行调用,请看示例:
示例代码:
class MyClass
{
    public static function fnCallBack( $msg1 , $msg2 )
    {
        echo 'msg1:'.$msg1;
        echo "
\n";
        echo 'msg2:'.$msg2;
    }
}


$className = 'MyClass'; //类名
$fnName = "fnCallBack";//类中的方法名
$params = array( 'hello' , 'world' );//传给参数的值
call_user_func_array( array( $className , $fnName ) , $params );


结果:


代码说明:
    这段代码和第1种方法的代码很相似,我们将类名(MyClass)也作为call_user_func_array的第1个参数传递进去,就可以实现类的静态方法的回调了。注意,这时call_user_func_array的第1个参数是一个数组了,数组的第1个元素是类名,第二个元素是要调用的函数名

如果我用这种方法调用一个类的非静态方法(也就是把static去掉),会出现什么结果呢?请看下面代码
class MyClass
{
    public function fnCallBack( $msg1 , $msg2 )
    {
        echo 'msg1:'.$msg1;
        echo "
\n";
        echo 'msg2:'.$msg2;
    }
}
$className = 'MyClass';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
最终运行的结果跟原来一样


2.3 对象的方法的回调

  我先用最原始的字符串形式的调用方法尝试了一下,如下所示:
class MyClass
{
    private $name = 'abc';
    public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
    {
        echo 'object name:'.$this->name;
        echo "
\n";
        echo 'msg1:'.$msg1;
        echo "
\n";
        echo 'msg2:'.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
$myobj->$fnName();

结果:


调用是成功了,不过如何把参数params传给这个方法呢,如果把params直接传进去,那么它会作为1个参数,怎么把params拆开来传进去呢?查了下PHP手册,找到了create_function函数,这个方法可以用字符串来创建一个匿名函数,好,有思路了,可以创建一个匿名的函数,在这个匿名函数中,调用我们的回调函数,并把参数传进去。
我先手动创建一个匿名函数anonymous,在这个函数中,用前面试出来的方法调用回调函数,如下所示:
class MyClass
{
    private $name = 'abc';
    public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
    {
        echo 'object name:'.$this->name;
        echo "
\n";
        echo 'msg1:'.$msg1;
        echo "
\n";
        echo 'msg2:'.$msg2;
    }
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
//匿名函数的构建
function anonymous()
{
    global $myobj;
    global $fnName;
    global $params;
    $myobj->$fnName( $params[0] , $params[1] );
}
anonymous();

成功了。效果如下:

参考文献:
http://myceo.blog.51cto.com/2340655/725411/
http://blog.chinaunix.net/uid-20684384-id-1895266.html
http://segmentfault.com/a/1190000002901770

http://www.abc3210.com/2012/phper_07/php-callback.shtml

非常感谢以上的参考文献以及博主!

版权声明:Hello,很高兴能在CSDN上和大家相遇!希望能和大家交上朋友!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP中的依賴注入:避免常見的陷阱PHP中的依賴注入:避免常見的陷阱May 16, 2025 am 12:17 AM

DependencyInjection(DI)inPHPenhancescodeflexibilityandtestabilitybydecouplingdependencycreationfromusage.ToimplementDIeffectively:1)UseDIcontainersjudiciouslytoavoidover-engineering.2)Avoidconstructoroverloadbylimitingdependenciestothreeorfour.3)Adhe

如何加快PHP網站:性能調整如何加快PHP網站:性能調整May 16, 2025 am 12:12 AM

到Improveyourphpwebsite的實力,UsEthestertate:1)emplastOpCodeCachingWithOpcachetCachetOspeedUpScriptInterpretation.2)優化的atabasequesquesquesquelies berselectingOnlynlynnellynnessaryfields.3)usecachingsystemssslikeremememememcachedisemcachedtoredtoredtoredsatabaseloadch.4)

通過PHP發送大規模電子郵件:有可能嗎?通過PHP發送大規模電子郵件:有可能嗎?May 16, 2025 am 12:10 AM

是的,ItispossibletosendMassemailswithp.1)uselibrarieslikeLikePhpMailerorSwiftMailerForeffitedEmailsending.2)enasledeLaysBetenemailstoavoidSpamflagssspamflags.3))

PHP中依賴注入的目的是什麼?PHP中依賴注入的目的是什麼?May 16, 2025 am 12:10 AM

DependencyInjection(DI)inPHPisadesignpatternthatachievesInversionofControl(IoC)byallowingdependenciestobeinjectedintoclasses,enhancingmodularity,testability,andflexibility.DIdecouplesclassesfromspecificimplementations,makingcodemoremanageableandadapt

如何使用PHP發送電子郵件?如何使用PHP發送電子郵件?May 16, 2025 am 12:03 AM

使用PHP發送電子郵件的最佳方法包括:1.使用PHP的mail()函數進行基本發送;2.使用PHPMailer庫發送更複雜的HTML郵件;3.使用SendGrid等事務性郵件服務提高可靠性和分析能力。通過這些方法,可以確保郵件不僅到達收件箱,還能吸引收件人。

如何計算PHP多維數組的元素總數?如何計算PHP多維數組的元素總數?May 15, 2025 pm 09:00 PM

計算PHP多維數組的元素總數可以使用遞歸或迭代方法。 1.遞歸方法通過遍歷數組並遞歸處理嵌套數組來計數。 2.迭代方法使用棧來模擬遞歸,避免深度問題。 3.array_walk_recursive函數也能實現,但需手動計數。

PHP中do-while循環有什麼特點?PHP中do-while循環有什麼特點?May 15, 2025 pm 08:57 PM

在PHP中,do-while循環的特點是保證循環體至少執行一次,然後再根據條件決定是否繼續循環。 1)它在條件檢查之前執行循環體,適合需要確保操作至少執行一次的場景,如用戶輸入驗證和菜單系統。 2)然而,do-while循環的語法可能導致新手困惑,且可能增加不必要的性能開銷。

PHP中如何哈希字符串?PHP中如何哈希字符串?May 15, 2025 pm 08:54 PM

在PHP中高效地哈希字符串可以使用以下方法:1.使用md5函數進行快速哈希,但不適合密碼存儲。 2.使用sha256函數提高安全性。 3.使用password_hash函數處理密碼,提供最高安全性和便捷性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

北端:融合系統,解釋
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
4 週前By尊渡假赌尊渡假赌尊渡假赌
<🎜>掩蓋:探險33-如何獲得完美的色度催化劑
2 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。