我在另一个在PHP 5.3中运行良好的函数中有这个匿名函数$ build_tree
function nest_list($list) {
$index = array();
index_nodes($list, $index);
$build_tree = function(&$value, $key) use ($index, &$updated) {
if(array_key_exists($key, $index)) {
$value = $index[$key];
$updated = true;
todel($key); }
};
do {
$updated = false;
array_walk_recursive($list, $build_tree);
} while($updated);
return $list;
}
function index_nodes($nodes, &$index) {
foreach($nodes as $key => $value) {
if ($value) {
$index[$key] = $value;
index_nodes($value, $index);
}
}
}
如何将其转换为PHP 5.2兼容代码?
答案 0 :(得分:1)
通常,您可以使用对象的方法执行此操作(回调可以是函数,也可以是对象的方法;后者允许您维护状态)。这样的事情(未经测试):
class BuildTree {
public $index, $updated = false;
public function __construct($index) {
$this->index = $index;
}
function foo(&$value, $key) {
if(array_key_exists($key, $this->index)) {
$value = $this-.index[$key];
$this->updated = true;
todel($key); }
}
}
do {
$build_tree_obj = new BuildTree($index);
array_walk_recursive($list, array($build_tree_obj, 'foo'));
} while($build_tree_obj->updated);
但是,array_walk_recursive
有一个特殊功能,允许我们传递第三个参数,这个值将传递给函数的每次调用。虽然值是通过值传递的,但我们可以巧妙地使用对象(PHP 5中的引用类型)来维护状态(来自How to "flatten" a multi-dimensional array to simple one in PHP?):
$build_tree = create_function('&$value, $key, $obj', '
if(array_key_exists($key, $index)) {
$value = $index[$key];
$updated = true;
todel($key); }
');
do {
$obj = (object)array('updated' => false);
array_walk_recursive($list, $build_tree, $obj);
} while($obj->updated);
答案 1 :(得分:0)
我认为如果不改变函数的方式,这是不可能的,因为PHP 5.3中没有一种机制可以让lambda函数从它调用的范围中更改变量(在这种情况下为$updated
)。
您可以像这样返回$updated
:
$build_tree = create_function('&$value,$key,$updated','
$index = '.var_export($index).';
if(array_key_exists($key, $index)) {
$value = $index[$key];
$updated = true;
todel($key); }
return $updated;
');
但是你必须这样称呼它:
$updated = $build_tree('the value','the key',$updated);