首页 > 开发 > PHP > 正文

PHP基于闭包思想实现的BT(torrent)文件解析工具实例详解

2024-05-04 22:45:48
字体:
来源:转载
供稿:网友

本文实例讲述了PHP基于闭包思想实现的torrent文件解析工具。分享给大家供大家参考,具体如下:

PHP对静态词法域的支持有点奇怪,内部匿名函数必须在参数列表后面加上use关键字,显式的说明想要使用哪些外层函数的局部变量。

function count_down($count){  return $func = function()    use($count,$func)  {    if(--$count > 0)      $func();    echo "wow/n";  };}$foo = count_down(3);$foo();

我本来是想这样的。但是不行,会在第7行调用$func的时候报错。

错误是Fatal error: Function name must be a string in - on line 7

反复试验后发觉,外部的匿名函数应该通过引用传值传给内部,否则是不行的:

function count_down($count){  return $foo = function()    use(&$count,&$foo)  {    echo $count."/n";    if(--$count > 0)      $foo();  };}$foo = count_down(4);$foo();

像上面这样写就对了。

下面是另一种方法:

function count_down_again($count){  return function()use($count)  {    printf("wow %d/n",$count);    return --$count;  };}$foo = count_down_again(5);while($foo() >0);

不过,这段代码有点小错误。编译虽然没错,但是$foo函数每次返回的都是4.

也就是use关键字看上去像是支持静态词法域的,在这个例子上,它只是对外层函数使用的变量作了一个简单拷贝。

让我们稍微修改一下,把第3行的use($count)改为use(&$count):

function count_down_again($count){  return function()use(&$count)  {    printf("wow %d/n",$count);    return --$count;  };}$foo = count_down_again(5);while($foo() >0);

这样才正确。

我个人使用的方式是基于类的,做成了类似下面的形式:

class Foo{  public function __invoke($count)  {    if($count > 0)      $this($count - 1);    echo "wow/n";  }}$foo = new Foo();$foo(4);

这样做的行为也是正确的。

这样不会像前一个例子那样失去了递归调用的能力。

虽然这是一个类,但是只不过是在手动实现那些支持闭包和静态词法域的语言中,编译器自动实现的动作。

其实今天早上,我本来准备用类scheme的风格写一个解析器的。可能稍微晚点吧。scheme风格的函数式编程是这样的:

function yet_another_count_down($func,$count){  $func($count);  if($count > 0)    yet_another_count_down($func,$count - 1);}yet_another_count_down(function($var){echo $var."/n";},6);

它不是很依赖静态词法域,虽然scheme对静态词法域的支持还是很不错的。它主要还是利用了first-class-function。当然,这也是一种典型的闭包。

我实现的torrent解析工具的代码如下:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表