PHP5.3 α2 已经放出1个多月了, 最近一直都忙一些私人的事情, 今天终于有点时间.

赶紧下来试用,  apache2.x + php5.3 alpha2

在php src目录下,

./configure --with-apxs2=/usr/sbin/apxs

make

sudo make install

重启, apache无法启动,直接Segmentation fault. 研究了半天也没找到原因, 后来在conf目录下偶然的grep了一下,发现了原因,原来我这个环境以前是php4, 所以apache load了2次php module, 

删除掉以后,重启apache, 一切正常...

赶紧来试试php5.3的新特性吧,在php.net上我们可以看到,php5.3的新特性有:

- Namespaces (documentation maybe out dated)
- Late static binding and __callStatic
- Lambda functions and closures
- Addition of the intl, phar (phar is scheduled for some more work a head of alpha2), fileinfo and sqlite3 extensions
- Optional cyclic garbage collection
- Optional support for the MySQLnd replacement driver for libmysql
- Windows older than Windows 2000 (Windows 98, NT4, etc.) are not supported anymore (details)
- New syntax features like NOWDOC, limited GOTO, ternary short cut "?:"

等我好好研究研究, 回头写点试用手记. 😉

2008.09.22 about lambda function:

PHP5.3开始支持Lambda风格的函数,如果大家对Js很熟悉的话, 对于这种风格的函数那就并不陌生了:

var func = function(para){

alert(para);

};

Lambda风格的函数,最初是(应该是,我猜测)由Lisp系语言中的匿名函数而来的, 在Scheme(Lisp系语言)中,定义一个匿名函数可以使用lambda关键字:

(define add1 (lambda(x)(+ x 1)));


在PHP中有很多可以使用回调函数的函数,比如array_map,array_walk, 我一直很郁闷的就是, 对于这样的函数,我必须要先定义个回叫函数,然后将回叫函数的字符串函数名作为参数传递,对于我这样的一个追求代码漂亮的人来说,我对这种方式简直可以说是深恶痛绝。

所以,在以前,我一直都是使用create_function来创建匿名函数, 可是用create_function的时候,函数体,参数都必须以字符串的方式传入,这样语法高亮就不能被应用,导致代码还是很ugly。

今天,我终于等到了PHP的Lamdba…

首先,让我们先用一个例子,来试试:

< ?php
$lambda_fuc = function($string){
print $string;
};
$lambda_fuc("laruence");
?>


在PHP5.3的特性介绍中,也说明了,对于一个包含lambda函数的变量来说,可以有3种调用方式:

$lambda ();
call_user_func ($lambda);
call_user_func_array ($lambda, array ());


另外,对于匿名函数来说,最重要的伴随物就应该是闭包了(closure), PHP5.3中也同样支持了闭包,这样,我们就可以使用这个特性,来创建一些流程相同,但是数据并不完全的函数族,举个简单的例子:

< ?php
function closure($var){
return function($string) use ($var){
print $string . "\n" . $var;
};
}
$func = closure("laruence");
$func("I am");
?>


当我们var_dump lambda函数的时候,会得到如下结果:

object(Closure)#1 (0) {
//process
}


在PHP5.3的特性介绍中,介绍了Lambda的实现具体机理:

在PHP的语法分析阶段,当遇到lambda函数申明的时候,会调用一个新加入的函数 zend_do_begin_lambda_function_declaration, 这个函数内部会以”lambda”作为参数来调用zend_do_begin_function_declaration,紧接着会以新加入的ZEND_DECLARE_LAMBDA_FUNCTION Opcode来替换生成的ZEND_DECLARE_FUNCTION,

在编译阶段,ZEND_DECLARE_LAMBDA_FUNCTION会创建一个Closure对象,然后将lambda函数的op_array保存,并使zend_call_fun和zend_is_callable_ex可以调用Closure对象。