【发布时间】:2011-09-16 16:49:04
【问题描述】:
这是我正在使用的 php_decoded JSON 结构的摘录:
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 替换目标值的函数,但是每当我尝试递归执行此操作时,该值都不会改变。到目前为止,这是我的代码:
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;
}
}
}
有趣的是,如果我像这样直接索引结构:
$key = &$json['NBBList']['$values'][0]['MPList']['$values'][0]['Eccentricity']
$key = "asdf";
值可以更改。似乎唯一的问题是递归。这听起来像是一个非常容易解决的问题,但我编程才不到一年,所以我可能只是错过了一些明显的东西。 >.>
哦,postvalue 和 postkey 值来自 HTML 表单提交。
--编辑-- print 语句只是用于调试。可以忽略。
编辑 2: 下面是函数的调用方式:
foreach ($_POST as $postkey => $postvalue)
{
if ($postvalue != ""){
print "$postkey => $postvalue\n";
$idCounter = 1;
replaceVal($json['NBBList']['$values'][0], $postkey, $postvalue, $idCounter, 0);
}
}
同样,打印语句用于调试目的。
附加信息:HTML 输入字段的名称是根据它们在 JSON 树中的顺序动态分配的数字。因此,增加变量 idCounter 对应于进入下一个输入字段。
Edit3:在 cmets 中添加到代码中。
【问题讨论】:
-
我从你的描述中看到你想用一个新的值替换一个键,但是从给出的代码来看,它做了更多的逻辑。你能显示一个例子吗?
-
是的,对不起。我试图使帖子尽可能简单。我在第二次编辑中添加了调用。
-
你能解释一下这个函数是做什么的吗?我能读到以下内容:如果水平低于阈值,它只会递归。达到级别时:对于每个元素,它检查是否
$idCounter == $postvalue。在这种情况下,它会将密钥替换为$value。在另一种情况下,它只是增加了$idCounter。 -
我只是在 cmets 中添加了详细说明。最低级别的键/值对在网页中由输入字段表示。这些输入字段的名称只是由先前文件中的计数器分配的。当 idCounter 等于 Postkey 时,该函数已到达所需键。然后应该只是用 Postvalue 替换该键的值。