Make code sweet.PHP特殊用法的一些总结(2)--PHP中的‘callback’回调
本章总结一下PHP中‘callback’的一些实用用法。
1. 什么是callback?
首先简单的介绍一下‘callback’,俗称‘回调’,是一种将一段可执行代码作为参数传递以供另一个函数调用的行为,回调在不同语言有不同的实现方式,几乎现在所有的主流语言都支持这个特性,我总结实现callback的主要方式有两种:
1.以C++、C#等静态语言为主的通过函数指针方式实现回调
2.以Ruby、JavaScript等动态语言为主的通过lambda表达式(也叫匿名函数)实现回调
关于‘callback’的详细定义可以参看维基百科:http://en.wikipedia.org/wiki/Callback_(computer_programming),
2.PHP中复杂的callback
说起callback,很多人马上回想起PHP 5.3的lambda函数实现方式,这个的确是实现callback最方便最养眼的一种方法,如果你有机会使用PHP 5.3,一定要狠狠的使用它。但是对于那些无法使用PHP 5.3或者必须兼容低版本的应用而言,其实PHP中还是有很多其他的callback实现方式,下面我们一一道来。
PHP支持函数指针的方式实现,实现规则如下:如果传一个函数,将函数名以字符串形式传给参数
如果传一个对象的方法,将一个数组传给参数,其中index=0的位置放对象,index=1的位置放方法名字符串
如果传一个类的静态方法,将一个数组传给参数,其中index=0的位置放类名字符串,index=1的位置放方法名字符串
PHP支持使用函数create_function创建匿名函数这个是PHP 5.3以下版本创建匿名函数的唯一方式,原型如下:
string create_function ( string $args , string $code )
登录后复制
不过这个函数中把函数的参数列表和实现都放到了字符串中,在编辑器中无法语法高亮,很容易出错,而且还要对代码中的字符进行转义,这些复杂性限制了PHP中匿名函数的使用。
就是前面提到的使用lambda函数(仅PHP 5.3及以上版本支持) 随着闭包、lambda函数在语言中的流行,PHP也支持了lambda函数,语法仿照了javascript的匿名函数,不过和Ruby、JavaScript的闭包不同的是它不能访问闭包外层的变量,除非使用use将变量显示的引入。
在PHP标准库中,如:array_map,usort等函数支持传递callback参数,你可以用上述任意方式作为参数。这样已经足够了,想实现一个函数,用户可以传递callback参数?当然没有问题,在参数列表中有一个callback参数,写着函数的实现,突然顿了顿,然后问出了如下问题:
3.如何在函数中调用callback
是啊,上面提到了如何构建callback参数,那如何在函数中执行这个参数呢?最容易想到的方式是
直接使用字符串变量来执行函数,比如:
$a='FunctionName';
$a();
登录后复制
这种方式直观,简单。不过这个方法不是对所有的callback形式的参数都有效,
如果想兼容所有的callback参数,可以使用以下的函数:call_user_func和call_user_func_array 这两个函数的用途是一样的,区别是call_user_func_array的函数传递给callback函数的参数必须用array排列,使用哪个凭个人喜好,我倾向使用call_user_func,字符少,参数更灵活。函数的原型如下:
mixed call_user_func ( callback $function [, mixed $parameter [, mixed $... ]] )
mixed call_user_func_array ( callback $function , array $param_arr )
登录后复制
为了提高函数的容错性,我们
需要在调用之前判断参数是否可以调用,这是可以使用如下函数:is_callable函数原型如下:
bool is_callable ( callback $name [, bool $syntax_only= false [, string &$callable_name ]] )
登录后复制
关于PHP中的callback就总结到这里。我的微博地址:http://weibo.com/jameren,欢迎大家关注,
。
顺便做个广告:
引用
我最近使用了15G超大空间免费网络U盘―@酷盘,可在PC及手机上使用,无文件类型及大小限制,传输速度快,文件永不丢失,一起来体验吧!通过下面的邀请链接注册,你和我都将额外获得256MB的酷盘空间! http://t.cn/aNLZje