1

i have a json file structured this way:

{
   "data": {
       "Category": {
           "Product1": [{
               "Code": "abc"
           }],
           "Product2": [{
               "Code": "cba"
           }]
       },
       "Category2": {
           "Product3": [{
               "Code": "abcabc"
           }],
           "Product4": [{
               "Code": "cbacba"
           }]
       },
       "Category3": {
           "Product5": [{
               "Code": "abcabcabc"
           }],
           "Product6": [{
               "Code": "cbacbacba"
           }]
       }
   }
}
                            

How can i change the category names with a php script? for example if i have 2 variables received from a form, called "$oldcategory" (which will be one of the existing categories) and "$newcategory" how can it, open the json file, place "$newcategory" where "$oldcategory" is and re-save the file?

<?php
$oldcategory= $_POST['oldcategory'];
$newcategory= $_POST['newcategory'];
$jsonString = file_get_contents('data.json');
$data = json_decode($jsonString, true);

...
foreach($data["data"] as $key=>$value){
    $new = $data["data"][$oldcategory];
    $data["data"][$newcategory]= $new ; 
}
unset($data["data"][$oldcategory]);

$newJsonString = json_encode($data);
file_put_contents('data.json', $newJsonString);
?>

in case i was changing the "Category2" i'd like the result to be:

{
   "data": {
       "Category": {
           "Product1": [{
               "Code": "abc"
           }],
           "Product2": [{
               "Code": "cba"
           }]
       },
       "New_Category2": {
           "Product3": [{
               "Code": "abcabc"
           }],
           "Product4": [{
               "Code": "cbacba"
           }]
       },
       "Category3": {
           "Product5": [{
               "Code": "abcabcabc"
           }],
           "Product6": [{
               "Code": "cbacbacba"
           }]
       }
   }
}
                            

instead of this:

{
   "data": {
       "Category": {
           "Product1": [{
               "Code": "abc"
           }],
           "Product2": [{
               "Code": "cba"
           }]
       },
       "Category3": {
           "Product5": [{
               "Code": "abcabcabc"
           }],
           "Product6": [{
               "Code": "cbacbacba"
           }]
       },
       "New_Category2": {
           "Product3": [{
               "Code": "abcabc"
           }],
           "Product4": [{
               "Code": "cbacba"
           }]
       }
   }
}
                            

This was a possible solution:

foreach($data["data"] as $key=>$value){
    if ($key == $oldcategory){
    $key = $newcategory;}
    $new["data"][$key] = $value;
}


$newJsonString = json_encode($new);
file_put_contents('data.json', $newJsonString);
  • 1
    Loop the array, find the value, replace it? Have you attempted anything? If so, please share your effort and explain where and how it fails to do what you want. – El_Vanja Apr 16 '21 at 13:51
  • i tried this: `foreach($data["data"] as $key=>$value){ if ($key == $oldcategory) { $key = $newcategory; } }` – Prancingkiller Apr 16 '21 at 13:56
  • Add it to the question using the "edit" button, please. But that looks like it covers trying to list the data...did it identify the record as you wanted? All you have to do then is remove / rename that element. is that the bit your're stuck on? – ADyson Apr 16 '21 at 13:57
  • 1
    When you do `$key = $newcategory;`, you're merely reassigning a temporary variable where the loop stores the key of the current element. To modify the array, you would need to assign a new value to it under that key: `$data['data'][$key] = $newcategory`. – El_Vanja Apr 16 '21 at 14:00
  • Or, maybe I misunderstood, and all you really want is to rename the category, meaning change the key? – El_Vanja Apr 16 '21 at 14:02
  • yeah i only need to change that key – Prancingkiller Apr 16 '21 at 14:03
  • Does this answer your question? [How to rename array keys in PHP?](https://stackoverflow.com/questions/9605143/how-to-rename-array-keys-in-php) – El_Vanja Apr 16 '21 at 14:04
  • Thanks a lot, i'm updating the question with the new code, it does create a new category with the modified key, and it deletes the old one, is there a way to keep it on the same order as it was before instead of going at the bottom of the list? – Prancingkiller Apr 16 '21 at 14:24
  • You'd have to sort it again afterwards, I think. Is the order significant later on, though, or not? – ADyson Apr 16 '21 at 14:25
  • yes, i'd need to keep the index of the old category and place the new one at the same place in the list where the old one was – Prancingkiller Apr 16 '21 at 14:29
  • Ah, that's not quite the same as sorting it then, because presumably there's a chance it wouldn't come out in the same order during an alphabetical sort (e.g. if old category is "ABC" and new category is "XYZ". So to be clear, do you want to place it literally in the same place, or you want the array to be sorted again using a specific criteria? Unfortunately I don't think you can change the order of the keys in a PHP array except by using one of the sorting functions. See https://stackoverflow.com/questions/10914730/are-php-associative-arrays-ordered – ADyson Apr 16 '21 at 14:32
  • But you might be able to do it indirectly by splicing the array - replace the section of the array after the correct offset with the contents which occurs after that offset + the new item prepended to it. https://www.php.net/manual/en/function.array-splice.php, https://www.php.net/manual/en/function.array-slice.php, https://www.php.net/manual/en/function.array-unshift.php might all be involved. Maybe there's a better way but that's what occurs to me off the top of my head. See also https://www.php.net/manual/en/ref.array.php and use your imagination! – ADyson Apr 16 '21 at 14:35
  • 1
    i've updated the question to be more clear, i'm gonna look at your suggestions thanks! – Prancingkiller Apr 16 '21 at 14:38
  • I see you added possible solution. That should go in the answers section along with other people's solutions. The answer is not part of the question :-) – ADyson Apr 16 '21 at 17:08
  • posted, i'm new and i don't know exactly how it works yet ^^ thanks for the help! – Prancingkiller Apr 16 '21 at 19:04

2 Answers2

2

This ended up being the solution to my problem:

<?php
$oldcategory= $_POST['oldcategory'];
$newcategory= $_POST['newcategory'];
$jsonString = file_get_contents('data.json');
$data = json_decode($jsonString, true);

...
foreach($data["data"] as $key=>$value){
    if ($key == $oldcategory){
    $key = $newcategory;}
    $new["data"][$key] = $value;
}

$newJsonString = json_encode($new);
file_put_contents('data.json', $newJsonString);
?>
  • I believe you may have posted the wrong code. The solution you gave, that you have embedded in your question, includes an `if` statement. – Andrew Hardiman Apr 17 '21 at 08:15
0

You could use a conditional, and create a new array with the desired values. When you reach the $oldcategory in your loop, replace the key with the $newcategory.

$newArray = [];
foreach($data["data"] as $key=>$value){
    if($key == $oldcategory) {
        $newArray[$newcategory] = $value;
    } else {
        $newArray[$key] = $value;
    }
}

$newJsonString = json_encode($newArray);
Andrew Hardiman
  • 929
  • 1
  • 15
  • 30
  • 1
    i think we ended up with a similar solution? check the last part of the question that i updated while you were typing the answer – Prancingkiller Apr 16 '21 at 15:52
  • @Prancingkiller yes, they effectively the same, I might like your solution even more, you should post it as an answer here also. – Andrew Hardiman Apr 16 '21 at 17:24