PHP 7 - 在回调中迭代填充多级数组
PHP 7 - iteratively populate multilevel array in callback
我只需要在回调中构建复杂的多级数组,每次调用一个原子更新。
原因:迭代解析器多次调用回调。最后,它应该构建反序列化的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()
,请参阅下面已接受的固定版本答案。
你可以做这样的事情,它肯定会简化你想做的事情。它只是具有不同的基本数组值,但足够相似,所以我认为它应该适用于您的应用程序。
所做的更改:重组数组并使用 addTo
字符串作为 'pointer'
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']));
我认为问题是 array_pop
没有 return 对最后一个元素的实际引用。这个有效:
<?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']));
我只需要在回调中构建复杂的多级数组,每次调用一个原子更新。
原因:迭代解析器多次调用回调。最后,它应该构建反序列化的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()
,请参阅下面已接受的固定版本答案。
你可以做这样的事情,它肯定会简化你想做的事情。它只是具有不同的基本数组值,但足够相似,所以我认为它应该适用于您的应用程序。
所做的更改:重组数组并使用 addTo
字符串作为 'pointer'
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']));
我认为问题是 array_pop
没有 return 对最后一个元素的实际引用。这个有效:
<?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']));