PHP基于闭包头脑实现的BT(torrent)文件理会器材实例详解
本篇章节讲授PHP基于闭包头脑实现的torrent文件理会器材。分享给各人供各人参考,详细如下: PHP对静态词法域的支持有点稀疏,内部匿名函数必需在参数列表后头加上use要害字,显式的声名想要行使哪些外层函数的局部变量。 0) $func(); echo "wown"; }; } $foo = count_down(3); $foo();我原来是想这样的。可是不可,会在第7行挪用$func的时辰报错。 错误是Fatal error: Function name must be a string in - on line 7 重复试验后觉察,外部的匿名函数应该通过引用传值传给内部,不然是不可的: 0)
$foo();
};
}
$foo = count_down(4);
$foo();
像上面这样写就对了。 下面是另一种要领: 0);不外,这段代码有点小错误。编译固然没错,可是$foo函数每次返回的都是4. 也就是use要害字看上去像是支持静态词法域的,在这个例子上,它只是对外层函数行使的变量作了一个简朴拷贝。 让我们轻微修改一下,把第3行的use($count)改为use(&$count): 0);这样才正确。 我小我私人行使的方法是基于类的,做成了相同下面的情势: 0) $this($count - 1); echo "wown"; } } $foo = new Foo(); $foo(4);这样做的举动也是正确的。 这样不会像前一个例子那样失去了递归挪用的手段。 固然这是一个类,可是只不外是在手动实现那些支持闭包和静态词法域的说话中,编译器自动实现的举措。 着实本日早上,我原来筹备用类scheme的气魄威风凛凛写一个理会器的。也许轻微晚点吧。scheme气魄威风凛凛的函数式编程是这样的: 0) yet_another_count_down($func,$count - 1); } yet_another_count_down(function($var){echo $var."n";},6);它不是很依靠静态词法域,固然scheme对静态词法域的支持照旧很不错的。它首要照旧操作了first-class-function。虽然,这也是一种典范的闭包。 我实现的torrent理会器材的代码如下: _file = $file;
}
public function __invoke($parent = array())
{
$ch = $this ->read();
switch($ch)
{
case 'i':
{
$n = $ch;
while(($ch = $this ->read()) != 'e')
{
if(!is_numeric($ch))
{
echo '在';
echo sprintf(
'0x%08X',ftell($this ->_file));
echo '理会数字时碰着错误',"rn";
echo '在i和e之间不该该呈现非数字字符'."rn";
echo '不测的字符'.sprintf('0x%02X',$ch);
exit();
}
else
{
$n .= $ch;
}
}
$n += 0;
$offset = count($parent['value']);
$parent['value'][$offset] = $n;
return $parent;
}
break;
case 'd':
{
$node = array();
//这个$node变量作为字典工具筹备插手到$parent的孩子节点中去
//$node['type'] = 'd';
while('e' != ($tmp = $this($node)))
{//每次给$node带来一个新孩子
$node = $tmp;
}
$child_count = count($node['value']);
if($child_count % 2 != 0)
{
echo '理会末了于';
echo sprintf('0x%08X',ftell($this ->_file));
echo '的字典时碰着错误:'."rn";
echo '字典的工具映射不匹配';
exit();
}
$product = array();
for($i = 0; $i < $child_count; $i += 2)
{
$key = $node['value'][$i];
$value = $node['value'][$i + 1];
if(!is_string($key))
{
echo '无效的字典末了于';
echo sprintf('0x%08X',ftell($this ->_file));
echo ":rn";
echo '理会[k => v]配对时碰着错误,k应为字符串';
exit();
}
$product[$key] = $value;
}
/*
* 头脑是这样的:子节点想要插手父节点时,
* 往父节点的value数组添加。
* 当父节点网络好所需的信息后,
* 父节点自身再从它的value节点整合内容
* 对付字典和列表同一这样处理赏罚会大大低落代码量
*/
$offset = count($parent['value']);
$parent['value'][$offset] = $product;
return $parent;
}
break;
case 'l';
{
$node = array();
while('e' != ($tmp = $this($node)))
{
$node = $tmp;
}
$offset = count($parent['value']);
$parent['value'][$offset] = $node['value'];
return $parent;
}
break;
case 'e':
return 'e';
break;
default:
{
if(!is_numeric($ch))
{
$this ->unexpected_character(
ftell($this ->_file) - 1,$ch);
}
$n = $ch;
while(($ch = $this ->read()) != ':')
{
$n .= $ch;
if(!is_numeric($n))
{
unexpected_character(
ftell($this ->_file) - 1,$ch);
}
}
$n += 0;
$str = '';
for(; $n > 0; --$n)
{
$str .= $this ->read();
}
$offset = count($parent['value']);
$parent['value'][$offset] = $str;
return $parent;
}
break;
}
}
/*
* read函数包裹了$this ->_file变量
*/
function read()
{
if(!feof($this ->_file))
{
return fgetc($this ->_file);
}else{
echo '不测的文件竣事';
exit();
}
}
/*
* unexpected_character函数吸取2个参数
* 它用于指明剧本在那里碰着了哪个不正当的字符,
* 并在返回前终止剧本的运行。
*/
function unexpected_character($pos,$val)
{
$hex_pos = sprintf("0x%08X",$pos);
$hex_val = sprintf("0x%02X",$val);
echo 'Unexpected Character At Position ';
echo $hex_pos.',Value '.$hex_val."rn";
echo "Analysing Process Teminated.";
exit();
}
}
?>
这里很风趣的是,显着我对文件挪用了 更多关于PHP相干内容感乐趣的读者可查察本站专题:《》、《》、《》、《》、《》、《》、《》、《》及《》、 但愿本文所述对各人PHP措施计划有所辅佐。 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |