全局函数的回调
这里的全局函数的意思,是直接使用function定义的函数,它不包含在任何对象或类之中。请看下面的例子
示例代码php
代码说明:
这里使用了PHP内置的函数call_user_func_array来进行调用。call_user_func_array有两个参数,第1个参数是一个字符串,表示要调用的函数名,第2个参数是一个数组,表示参数列表,按照顺序依次会传递给要调用的函数。
效果以下:
类的静态方法的回调
若是咱们要回调的方法,是一个类的静态方法,那怎么办呢?咱们依然能够利用PHP内置的call_user_func_array方法来进行调用,请看示例:
示例代码:
面试
代码说明:
这段代码和第1种方法的代码很类似,咱们将类名(MyClass)也做为call_user_func_array的第1个参数传递进去,就能够实现类的 静态方法的回调了。注意,这时call_user_func_array的第1个参数是一个数组了,数组的第1个元素是类名,第二个元素是要调用的函数名
运行结果:
(其实和第1种方法的结果是同样的 ^_^ )
继续研究
若是我用这种方法调用一个类的非静态方法(也就是把static去掉),会出现什么结果呢?请看下面代码
数组
运行结果
和前面的结果仍是同样的。。。
如今我为这个类添加一点属性,并在方法中引用
函数
运行结果
出现解析错误,提示$this没有在对象环境下出现,说明这个方法不能用类来调用,而是要用对象来调用。那咱们就修改一下代码,建立一个对象:
this
运行结果:
提示call_user_func_array的第1个参数非法,也就是说,调用失败。看来咱们不能用call_user_func_array方法来回调一个对象的方法了,那么如何实现对象方法的回调的?
对象的方法的回调
我先用最原始的字符串形式的调用方法尝试了一下,以下所示:
spa
成功了,输出结果
调用是成功了,不过如何把参数params传给这个方法呢,若是把params直接传进去,那么它会做为1个参数,怎么把params拆开来传进去呢?
查了下PHP手册,找到了create_function函数,这个方法能够用字符串来建立一个匿名函数,好,有思路了,能够建立一个匿名的函数,在这个匿名函数中,调用咱们的回调函数,并把参数传进去。
我先手动建立一个匿名函数anonymous,在这个函数中,用前面试出来的方法调用回调函数,以下所示:
设计
成功了,能够看到,对象的属性name也输出来了
而后,我用create_function来建立这个匿名函数,同时,代码中的params[0],params[1]应该是动态生成的,代码以下:
对象
这段代码能够定义一个匿名函数,并保存在$anonymous变量中,最后调用这个$anonymous,实现了方法的回调,如图
PHP事件模型(观察者模式)的实现思路
至此,PHP中的3种常见的函数类型(全局函数,类静态函数,对象的方法)均可以回调了,能够实现文章一开始说的事件模型了 :)
事件模型模仿Firefox的Javascript实现,有3个方法,分别是
blog
不过,因为第二、第3种方法须要传递上下文(也就是类名和对象名),因此addEventListener和removeEventListener应该有3个参数,我是这样设计的:
事件
第1个参数表示事件名,字符串类型
第2个参数表示回调函数名,字符串类型
第3个参数$scope是上下文环境,一共有3种类型,null表示传入的handler函数是一个全局函数,字符串类型表示传入的handler函数是scope类的静态函数,对象类型表示传入的scope是一个对象,handler函数是对象的一个方法。
这个方法内,会读取出全部响应evtName的handler,而后判断它对应的scope,若是是null,则用本文第1种方法回调,若是是字符串,则 用本文第2种方法回调,若是是对象,则用本文第3种方法回调。这样,一个PHP的事件模型就能够实现了,并且能够将回调函数放在某个对象中。