0

I am trying to update a JSON file via php, but what the current code is doing is appending the new object instead of replacing it. Here's a snippet of the JSON:

[
    {
        "id": 3,
        "title": "SOME MODS",
        "date": "Aug\/Sept 2017",
        "done": "yes",
        "files changed": {
            "1": "index.html",
            "2": "style.css"
        },
        "backend changes\/additions": {
            "1": "added some stuff"
        },
        "additions": {
            "1": "logo.jpg"
        }
    }
]

Basically what I want to do is on click of a button call an AJAX function to hit a php file. Then check to see if the passed id matches an id from the JSON file, then updated the "done" property... if no make it yes, if yes make it no.

Here's my PHP code:

if ( isset( $_POST['comp'] ) ) {
   $newObj = $_POST['comp'];

   $jsonFile = file_get_contents('data.json');
   $temp = json_decode($jsonFile, true);

   $tempArray;

   foreach( $temp as $e ){
      if( $e['id'] == $newObj ) {
         if ( $e['done'] === 'no' ){
            $e['done'] = 'yes';
            $tempArray = $e;
         } else {
            $e['done'] = 'no';
            $tempArray = $e;
         }
      }
   }

   $temp[] = $tempArray;
   $final_data = json_encode($temp, JSON_PRETTY_PRINT);
   file_put_contents('data.json', $final_data);

   print_r( $temp );

But as I mentioned, as it stands all it is doing is inserting a new Object instead of replacing. What do I need to change to make this functionality work?

Thank you all.

-S

5
  • $temp[] appends to $temp. Remove []. Commented Sep 15, 2017 at 21:06
  • here $temp[] = $tempArray; you are adding the new content. Commented Sep 15, 2017 at 21:06
  • I think you want to foreach by reference. This way you can walk through the array and change the values you wanna change. Commented Sep 15, 2017 at 21:08
  • @endrju yes you are right... but if I do that, then, it erases all the other records in the JSON file and just stores the newly modified obj. Commented Sep 15, 2017 at 21:09
  • @Jeff Yes you are correct in your first comment, but as I mentioned to endrju, if I remove the brackets in var, it then removes all the other Objects in the JSON file. Commented Sep 15, 2017 at 21:11

1 Answer 1

3

You want to pass $e by reference in your foreach:

<?php
// this originally comes from file
$json = <<<EOT
   [
    {
        "id": 3,
        "title": "SOME MODS",
        "date": "Aug\/Sept 2017",
        "done": "yes",
        "files changed": {
            "1": "index.html",
            "2": "style.css"
        },
        "backend changes\/additions": {
            "1": "added some stuff"
        },
        "additions": {
            "1": "logo.jpg"
        }
    }
]
EOT;

$temp = json_decode($json, true);
$newObj=3;  // this is only here for testing

         // here's the trick: the & before $e
foreach( $temp as &$e ){
  if( $e['id'] == $newObj ) {
     if ( $e['done'] === 'no' ){
        $e['done'] = 'yes';
     } else {
        $e['done'] = 'no';
     }
  }
}
$final_data = json_encode($temp, JSON_PRETTY_PRINT);
file_put_contents('data.json', $final_data);

This way you don't need another array and can save $temp back to your json file.

Short explanation (cracks, please correct me):
in your foreach php makes a copy of $e, so you have to write it back - as you've tried.
When you pass it by reference you work on the original item $e, not a copy. This way you can manipulate it directly.

Sign up to request clarification or add additional context in comments.

1 Comment

It's a great feature, but use it carefully. Especially when writing functions/methods. You don't want to have a function where you don't know what it might change.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.