Вот выдержка из структуры 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-формы.
–edit– Оператор печати находится там для отладки. Его можно игнорировать.
Редактировать 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: добавлен в комментарии к коду.