转换PHP 5.3匿名函数到5.2兼容功能

问题描述:

我有一个在PHP 5.3转换PHP 5.3匿名函数到5.2兼容功能

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); 
       } 
    } 
} 

工作正常,另一个函数内这个匿名函数$ build_tree我怎么能转换成PHP这个5.2兼容的代码?

+2

http://*.com/questions/5869084/php-5- 3-0-use-keyword – malletjo

+0

我想我们还需要周围的代码来说明如何使用这个函数来正确地重写算法。 – deceze

+0

我已经更新了所有周边代码和相关功能的问题 – Justin

我不认为这是可能的,而不改变功能调用的方式,因为在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); 
+0

但'array_walk_recursive'(提问者正在使用)不会将任何数据返回给您 – user102008

,你可以做到这一点使用对象的方法(回调可以是一个函数或一个对象的方法;后者允许你保持状态)。像这样的东西(未测试):

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);