PHP 问题在 JSON 数组中递归更改键值 [英] PHP Problem changing key values recursively in JSON array

查看:48
本文介绍了PHP 问题在 JSON 数组中递归更改键值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在使用的 php_decoded JSON 结构的摘录:

Here is an exerpt from the php_decoded JSON structure that I am working with :

array(3) {
  ["$type"]=> string(51) "NanoWebInterpreter.WebInputData, NanoWebInterpreter"
  ["NBBList"]=>
    array(2) {
    ["$type"]=> string(81) "System.Collections.Generic.List`1[[monoTNP.Common.NBB, monoTNP.Common]], mscorlib"
    ["$values"]=>
    array(1) {
      [0]=>
      array(6) {
        ["$type"]=> string(34) "monoTNP.Common.NBB, monoTNP.Common"
        ["ID"]=> string(16) "id-0065-00000003"
        ["MPList"]=>
        array(2) {
          ["$type"]=> string(80) "System.Collections.Generic.List`1[[monoTNP.Common.MP, monoTNP.Common]], mscorlib"
          ["$values"]=>
           array(3) {
            [0]=>
            array(9) {
              ["$type"]=> string(43) "monoTNP.Common.EllipticalMP, monoTNP.Common"
              ["Eccentricity"]=> float(1)
              ["ID"]=> string(16) "id-0065-00000006"
              ["ParticleIndex"]=> int(-1)
              ["DispersionInteractionStrength"]=> float(0)
              ["DispersionInteractionRange"]=> float(2.5)
              ["CharacteristicSize"]=> float(0)
              ["CenterOfMass"]=> string(7) "<0,0,0>"
              ["OrientationVector"]=> string(2) "<>"
            }

我一直在尝试编写递归跟踪 JSON 对象并用 $postvalue 替换目标值的函数,但是每当我尝试递归执行此操作时,该值都不会更改.到目前为止,这是我的代码:

I have been trying to write this function that recursively traces the JSON object and replaces the target value with $postvalue, but whenever I try to do this recursively, the value isn't changed. Here is my code so far:

function replaceVal(&$json, $postkey, $postvalue, &$idCounter, $level)
{
        $depth = 3;

    #Base Case 
    #At the right depth level, check to see if the idCounter is equal to the
    #postkey value (the HTML input field name). If it is, take the  
    #corresponding key and assign the postvalue to it (the input from form).
    #Then return. Otherwise, incrememnt the idCounter and return.
        if ($level >= $depth){
                foreach($json as $key => $value){
                        if($idCounter == $postkey){
                                print "$key => $value\n";
                                $json[$key] = $postvalue; #Not working properly
                                return;
                        }
                        $idCounter++;
                }
        }

    #Descend down into the level of the tree specified by $depth. 
    #This level should correspond do the level at which the HTML input 
    #fields lie
    #$idCounter will only be greater than $postkey if the value has 
    #been changed by the previous if statement. In that case, the job is done
    #and the function will terminate.

        if ($level < $depth){
                foreach($json as $key => $value){
                        if ($idCounter < $postkey)
                                replaceVal($value, $postkey, $postvalue, $idCounter, $level+1);
                        else
                                return;
                }
         }
}

有趣的部分是,如果我像这样直接索引到结构中:

The interesting part is that if I directly index into the structure like so:

$key = &$json['NBBList']['$values'][0]['MPList']['$values'][0]['Eccentricity']
$key = "asdf";

该值可以更改.唯一似乎有问题的是递归.这听起来是一个很容易解决的问题,但我编程的时间还不到一年,所以我可能只是遗漏了一些明显的东西.>.>

The value can be changed. The only thing that seems to be the problem is the recursion. This sounds like a really easy problem to fix, but I've only been programming for a little less than a year so I am probably just missing something obvious. >.>

哦,postvalue 和 postkey 值来自 HTML 表单提交.

Oh and the postvalue and postkey values come from an HTML form submission.

--编辑--打印语句只是在那里进行调试.可以忽略.

--edit-- The print statement is just in there for debugging. It can be ignored.

以下是该函数的调用方式:

Edit 2: Here is how the function is called:

foreach ($_POST as $postkey => $postvalue)
{
        if ($postvalue != ""){
                print "$postkey => $postvalue\n";
                $idCounter = 1;
                replaceVal($json['NBBList']['$values'][0], $postkey, $postvalue, $idCounter, 0);
        }
}

同样,print 语句是为了调试目的.附加信息:HTML 输入字段的名称是根据它们在 JSON 树中的顺序动态分配的数字.因此,增加变量 idCounter 对应于继续下一个输入字段.
Edit3:在代码注释中添加.

Again, the print statement is for debugging purposes. Additional info: The names of the HTML input fields are dynamically assigned numbers based on their order in the JSON tree. So, incrementing the variable idCounter corresponds to proceeding to the next input field.
added in comments to code.

推荐答案

您可以(并且应该)始终使用 PHP 的内部函数,以防万一.

You can (and should) allways use PHP's internal function, in case there is any.

如果你不需要计数器,你可以看看array_replace_recursive.在这种情况下,您的代码将如下所示:

If you don't need the counter, you could look at array_replace_recursive. In that case, your code would look like this:

function replaceVal(&$array, $key, $value) {
    $array = array_replace_recursive( $array, array( $key => $value ) );
}

编辑

在当前评论之后:

function replaceVal(&$json, $postkey, $postvalue, &$idCounter, $level)
{
    $depth = 3;

    if ($level >= $depth){
            foreach($json as $key => $value) {
                    if($idCounter == $postkey) {
                            $json[$key] = $postvalue; #Not working properly
                            return;
                    }
                    $idCounter++;
            }
    }

    if ($level < $depth){
            foreach($json as $key => $value){
                    if ($idCounter < $postkey)
                            replaceVal($json[$key], $postkey, $postvalue, $idCounter, $level+1);
                    else
                            return;
            }
     }
}

问题是,在递归中,您使用 $value,这是数组元素的副本.然后,它被编辑,但更改没有传播到 $json.

The problem was that, in the recursion, you where using $value, wich is a copy of the array element. Then, that was edited, but the changes didn't propagate to $json.

这篇关于PHP 问题在 JSON 数组中递归更改键值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆