改变php中多维数组的内容?

时间:2013-07-28 14:18:16

标签: php json

我在php中有一个多维数组,我想按照一些规则进行操作。

输入阵: (变量打印为JSON)

[
    {
        "meta":{
                "title": "Adressdata",
                "name": "adress"
        },    
        "data":{
            "desc":{    "tooltip":  "text",
                        "maxlength":    "100"
                },
            "line1":{   "tooltip":  "Recipient",
                        "maxlength":    "40"
                }
    }
]

规则:

{
    "0>meta>title": "Companyaddress",
    "0>data>desc": {
        "tooltip": "Another Text",
        "maxLength": "150"
    }
}

(有两个规则,索引说明输入数组中的哪个字段必须更改,并且该值包含要插入的数据。请注意,第二个规则要插入对象)< / em>的

问题:

我想根据规则更改输入数组的内容,但我很难做到这一点。

这是我已经拥有的php-Code:

<?php
    $input = json_decode(file_get_contents("inputData.json"),true);
    $rules = json_decode(file_get_contents("rules.json"),true);

    foreach ($rules as $target => $replacement) {       
        //rule:  "0>meta>title": "newTitle"

        $node = $input;
        foreach (explode(">",$target) as $index) {
            $node = $node[$index];
        }

        $node = $replacement;   //replace doesn't work    
    }

    echo "Result-Array: ";
    print_r($input);
?>

一切都有效,除了我无法改变价值观。 为什么?因为每次我设置$ node-Variable,我都会创建一个新的Variable。 我只更改$ node的内容,但不更改$ input的内容。

所以我尝试使用引用 - 这也不起作用: 当我将2 $ node-Lines更改为此代码时:

$node = &$input;
[...]
$node = &$node[$keys[$i]];  //go to child-node

但是这不起作用,因为我只想导航到子节点的第二行改变了父元素(因为$ node是一个引用)。

我不知道是否有诀窍,我希望有人可以帮助我

2 个答案:

答案 0 :(得分:1)

好的,这是一些决定,您应该更改$rules结构,它应该与$input相同:

$input = json_decode('[{"meta":{"title": "Adressdata","name": "adress"},"data":{"desc":{"tooltip":"text","maxlength":"100"},"line1":{"tooltip":"Recipient","maxlength":"40"}}}]',true);
$rules = json_decode('[{"meta":{"title": "Companyaddress"},"data":{"desc":{"tooltip":"Another Text","maxlength":"150"}}}]',true);

 // if you print both arrays you will see that they have the similar structure
 // but $rules consists only of items that you need to change.
 // next:
 echo'<pre>',print_r(array_replace_recursive($input, $rules)),'</pre>';

 // BINGO!

答案 1 :(得分:0)

好的,经过一段令人沮丧的时间后,我终于找到了实现这一目标的方法。

这是我写的函数:

/**
 * Manipulates an array according to the given rules
 */
function manipulateData($input, $manipulations){

    foreach ($manipulations as $target => $replacement) {   //for each rule 
        $tmpRefNum = 0;                              //Variable-Nameprefix for the reference (don't generate random names)

        $node = "node".(++$tmpRefNum);               //"node1"
        $$node = &$input;                            //$node1 --> $input

        foreach (explode(">",$target) as $index) {   //for each child in the rule           
            $parent = &$$node;                       //We search for a child. So the old node becomes a parent

            if(!isset($parent[$index])){             //Does the child exist?        no --> create missing child             
                $parent[$index] = "";                //give birth! (value will be set later)                
            }

            $node = "node".(++$tmpRefNum);           //Generate a new reference-Name: "node2", "node3", ...
            $$node = &$parent[$index];               //Point to child        
        }

        $$node = $replacement;                       //Change the child-content

        //Unset all generated references (just to not spam the variables)
        /* */   for($i=1;$i<=$tmpRefNum;$i++){
        /* */       $node = "node".$i;
        /* */       unset($$node);
        /* */   }
        /* */   
    }
    return $input;
}

说明

解决方案是,我只为我找到的每个子节点生成一个新的变量/引用。为了做到这一点,我需要php提供的$$ - 语法。

它有点脏,因为我有一个变量工厂,所以如果有人找到一个更好的解决方案,它会很棒。

如果这是一个很好的解决方案,我会得到一些反馈,这将是很好的。