Конвертировать анонимную функцию PHP 5.3 в 5.2 совместимую функцию - PullRequest
3 голосов
/ 23 ноября 2011

У меня есть эта анонимная функция $ build_tree в другой функции, которая отлично работает в PHP 5.3

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 совместимый код?

Ответы [ 2 ]

1 голос
/ 09 июня 2012

Как правило, вы можете сделать это, используя метод объекта (обратные вызовы могут быть либо функцией, либо методом объекта; последний позволяет вам поддерживать состояние). Как то так (не проверено):

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) для поддержания состояния (от Как «сгладить» многомерный массив до простого в 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);
0 голосов
/ 23 ноября 2011

Я не думаю, что это возможно без изменения способа вызова функции , потому что в PHP 5.3 нет механизма для лямбда-функции, чтобы изменить переменную из области, в которой она вызывается (в этом случае $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);
...