【问题标题】:PHP 7 - iteratively populate multilevel array in callbackPHP 7 - 在回调中迭代地填充多级数组
【发布时间】:2018-09-28 00:12:16
【问题描述】:

我只需要在回调中构建复杂的多级数组,每次调用一次原子更新。

原因:迭代解析器多次调用回调。最后它应该构建被解析的二进制格式的反序列化 PHP 数组。

这是可运行的代码:

const ACTION_VALUE = 1;
const ACTION_ENTER = 2;
const ACTION_LEAVE = 3;

function callback($action, $value, &$param)
{
   switch ($action) 
   {
    case ACTION_ENTER:
        $param['parent'][] = &$param['current'];
        $param['current'][] = [];

        end($param['current']);                
        $param['current'] = &$param['current'][key($param['current'])];
    break;

    case ACTION_LEAVE:
        unset($param['current']);
        $param['current'] = array_pop($param['parent']);
        end($param['current']);
    break;

    case ACTION_VALUE:
        $param['current'][] = $value;
    break;
   }
}

// prepare container
$arr = [];
$arr['data'] = [];
$arr['current'] = &$arr['data'];
$arr['parent'] = [];

// callback invocations
callback(ACTION_VALUE, 1, $arr);
callback(ACTION_VALUE, 2, $arr);
callback(ACTION_ENTER, 0, $arr);
callback(ACTION_VALUE, 10, $arr);
callback(ACTION_VALUE, 11, $arr);
callback(ACTION_LEAVE, 0, $arr);
callback(ACTION_VALUE, 3, $arr);
callback(ACTION_VALUE, 4, $arr);

// now see result
var_dump(json_encode($arr['data']));

试试here

以上示例打印:

[1,2,[10,11]],但应该 [1,2,[10,11],3,4].

更新: 多级表示随机深度的任意数组。

更新: 问题出在array_pop(),请参阅下面接受的固定版本答案。

【问题讨论】:

  • 您可以尝试作为指针进入和离开吗?离开时,将其添加到数据中,然后将指针指向主数据?
  • 如果您的意思是,将不同的“上下文”传递给回调?不,我不能,因为解析器调用了回调,并且解析器对回调的使用方式一无所知......它只是通过 &$param 进行所有回调调用,对 &$param 是什么一无所知。

标签: php pass-by-reference recursive-datastructures


【解决方案1】:

你可以做这样的事情,它肯定会简化你想要做的事情。它只是具有不同的基本数组值,但足够相似,所以我认为它应该适用于您的应用程序。

所做的更改:重组数组并使用addTo 字符串作为“指针”

const ACTION_VALUE = 1;
const ACTION_ENTER = 2;
const ACTION_LEAVE = 3;

// prepare container
$arr = [];
$arr['data'] = [];
$arr['addTo'] = 'data';
$arr['temp'] = [];

function callback($action, $value, &$param)
{
    switch ($action)
    {
        case ACTION_ENTER:
            $param['addTo'] = 'temp';
            break;

        case ACTION_LEAVE:
            $param['addTo'] = 'data';
            $param['data'][] = $param['temp'];
            $param['temp'] = [];
            break;

        case ACTION_VALUE:
            $param[$param['addTo']][] = $value;
            break;
    }
}



// callback invocations
callback(ACTION_VALUE, 1, $arr);
callback(ACTION_VALUE, 2, $arr);
callback(ACTION_ENTER, 0, $arr);
callback(ACTION_VALUE, 10, $arr);
callback(ACTION_VALUE, 11, $arr);
callback(ACTION_LEAVE, 0, $arr);
callback(ACTION_VALUE, 3, $arr);
callback(ACTION_VALUE, 4, $arr);

// now see result
var_dump(json_encode($arr['data']));

【讨论】:

  • 谢谢,但不幸的是,这种方法不适用于 3+ 嵌套级别。我不能以这种方式构建任意数组。
【解决方案2】:

我认为问题在于array_pop,它不会返回对最后一个元素的实际引用。这个有效:

<?php

const ACTION_VALUE = 1;
const ACTION_ENTER = 2;
const ACTION_LEAVE = 3;

function callback($action, $value, &$param)
{
    switch ($action) {
        case ACTION_ENTER:
            $param['parent'][] = &$param['current'];
            $param['current'][] = [];

            end($param['current']);
            $param['current'] = &$param['current'][key($param['current'])];
            break;

        case ACTION_LEAVE:
            unset($param['current']);
            end($param['parent']);
            $param['current'] = &$param['parent'][key($param['parent'])];
            unset($param['parent'][key($param['parent'])]);
            end($param['current']);
            break;

        case ACTION_VALUE:
            $param['current'][] = $value;
            break;
    }
}

// prepare container
$arr = [];
$arr['data'] = [];
$arr['current'] = &$arr['data'];
$arr['parent'] = [];

// callback invocations
callback(ACTION_VALUE, 1, $arr);
callback(ACTION_VALUE, 2, $arr);
callback(ACTION_ENTER, 0, $arr);
callback(ACTION_VALUE, 10, $arr);
callback(ACTION_VALUE, 11, $arr);
callback(ACTION_ENTER, 0, $arr);
callback(ACTION_VALUE, 40, $arr);
callback(ACTION_VALUE, 41, $arr);
callback(ACTION_LEAVE, 0, $arr);
callback(ACTION_LEAVE, 0, $arr);
callback(ACTION_VALUE, 3, $arr);
callback(ACTION_VALUE, 4, $arr);

// now see result
var_dump(json_encode($arr['data']));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2017-02-25
    • 2020-01-10
    • 2017-12-24
    相关资源
    最近更新 更多