PHP / json编码错误地解释为关联数组

时间:2017-06-27 07:59:11

标签: php arrays json

Edit1:问题:我想在php中将关联数组转换为索引数组。所以我可以通过json_encode作为数组而不是作为对象返回它。为此,我尝试填补丢失的密钥。这里描述:

遇到一个小问题,我需要将一个json_encoded数组作为数组传输给js。目前它返回一个Object。我正在使用Angular,所以我真的需要一个数组。我试着尽可能地解释它。

$arrNew[0][5][0][0][1]["id"] = 1;
//$arrNew[0][0][0][0][1] = "";
//$arrNew[0][1][0][0][1] = "";
//$arrNew[0][2][0][0][1] = "";
//$arrNew[0][3][0][0][1] = "";
//$arrNew[0][4][0][0][1] = "";
$arrNew[0][5][0][0][1]["name"] = 'Test';
var_dump($arrNew);

enter image description here

所以,如果我现在返回它返回第二个元素作为缺失索引0-4的对象原因和缺少索引0的第四个元素原因(关联数组 - >对象)

因此,如果我取消注释该块,它就像一个魅力。现在我遇到的问题不是每次元素5有时3,4或其他什么,所以我构建了一个自动添加它们的函数:

$objSorted = cleanArray($arrNew);
function cleanArray($array){
    end($array);
    $max = key($array) + 1; //Get the final key as max!
    for($i = 0; $i < $max; $i++) {
        if(!isset($array[$i])) {
            $array[$i] = '';
        } else {
            end($array[$i]);
            $max2 = key($array[$i]) + 1;
            for($i2 = 0; $i2 < $max2; $i2++) {
            .... same code repeats here for every index

所以,如果我vardump它返回: enter image description here

问题: 在js方面它仍然是一个对象,我也看到的是元素没有排序。所以我认为PHP看起来仍然是一个关联数组。任何线索为什么会这样?密钥使用循环的索引设置,并且必须是整数值。

PS:我知道在JS中重新编写它是可能的,但几乎每次请求都会有大量的循环

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你可以创建一个稀疏的多维对象数组。因为数组中的数组有间隙,json_encode()会在某些级别上生成对象,但是您需要它来为除最内层之外的所有级别生成数组。

以下函数在所有阵列级别上填充缺少的键(从0开始,直到数组中用作数字键的最大值)。然后它按键对每个数组进行排序,以确保json_encode()将其编码为数组而不是对象。

需要排序,否则json_encode()会生成一个对象;在note文档页面上的json_encode()中解释了此行为:

  

当对数组进行编码时,如果键不是从0开始的连续数字序列,则所有键都被编码为字符串,并为每个键值对明确指定。

// If $arr has numeric keys (not all keys are tested!) then returns
// an array whose keys are a continuous numeric sequence starting from 0.
// Operate recursively for array values of $arr
function fillKeys(array $arr)
{
    // Fill the numeric keys of all values that are arrays
    foreach ($arr as $key => $value) {
        if (is_array($value)) {
            $arr[$key] = fillKeys($value);
        }
    }

    $max = max(array_keys($arr));
    // Sloppy detection of numeric keys; it may fail you for mixed type keys!
    if (is_int($max)) {
        // Fill the missing keys; use NULL as value
        $arr = $arr + array_fill(0, $max, NULL);
        // Sort by keys to have a continuous sequence
        ksort($arr);
    }

    return $arr;
}

// Some array to test
$arrNew[0][5][0][0][1]["id"] = 1;
$arrNew[0][3][0][2][1]["id"] = 2;
$arrNew[0][5][0][0][1]["name"] = 'Test';


echo("============= Before ==============\n");
echo(json_encode($arrNew)."\n");

$normal = fillKeys($arrNew);

echo("============= After ==============\n");
echo(json_encode($normal)."\n");

输出:

============= Before ==============
[{"5":[[{"1":{"id":1,"name":"Test"}}]],"3":[{"2":{"1":{"id":2}}}]}]
============= After ==============
[[null,null,null,[[null,null,[null,{"id":2}]]],null,[[[null,{"id":1,"name":"Test"}]]]]]

$arr = $arr + array_fill(0, $max, NULL);行使用NULL作为缺失键的值。我认为这是解析数组的最佳代码(您可以使用if (! arr[0])来检测虚拟值)。

您可以使用空字符串('')代替NULL来获得更短的JSON:

[["","","",[["","",["",{"id":2}]]],"",[[["",{"id":1,"name":"Test"}]]]]]

但它需要在JS端稍长的代码来检测虚拟值(if (arr[0] != ''))。