elkefreed
elkefreed

Reputation: 964

Update JSON value if exists otherwise add it in PHP

I have a JSON file that contains the following:

{"faqitem": [{ "id": "faq1", "question": "Question 1"}]}

I am trying to do two things. Update a particular value if it exists OR add a new value if it doesn't.

Currently, I am able to update the file, but it just keeps adding new values and never updates if it already exists.

$faqpage = 'includes/faq.json';

$file = file_get_contents($faqpage);    
$obj = json_decode($file); 

$newdata['id'] = "faq2";
$newdata['question'] = "This is the second question";

foreach($obj->faqitem as $key => $val ) {
   echo "IDS " . $val->id . " = " . $newdata['id'] . "<br/>\n";
   if ($val->id == $newdata['id']) {
     $val->question = $newdata['question'];
     echo $val->id . "<br/>match<br/>";
   } else {
         $newstuff = new stdClass;
     $newstuff->id = $newdata['id'];
     $newstuff->question = $newdata['question'];     
     array_push($obj->faqitem, $newstuff);
     echo "<br/>no match<br/>";
   }
}

echo json_encode($obj);

$fh = fopen($faqpage, 'w') or die ("can't open file");  
//okay now let's open our file to prepare it to write
fwrite($fh, json_encode($obj));
fclose($fh);

Here is an example output with duplicated object ids:

{"faqitem":[{"id":"faq1","question":"Question 1"},{"id":"faq2","question":"This is the updated question"},{"id":"faq2","question":"This is the updated question"}]}

Upvotes: 0

Views: 2731

Answers (2)

Mike Brant
Mike Brant

Reputation: 71424

So take the whole JSON aspect out of it. That is just serialization. Think about how to make the data structure look the way you want. Think about your data structure. To me, it seems that is maybe not the best structure for your purposes and that perhaps you need your id available as a lookup key, so when you add an item to the data structure your either create a new value at that id key or overwrite the value at that key.

If your data were structured like:

{"faqitem":
    {
        "faq1": "Faq content",
        "faq2": "Faq 2 content"
    }
}

Then your code code be as simple as:

$faqpage = 'includes/faq.json';

$file = file_get_contents($faqpage);    
$obj = json_decode($file); 

$newdata['id'] = "faq2";
$newdata['question'] = "This is the second question";

$obj->faqitem->{$newdata['id']} = $newdata['question'];

echo json_encode($obj);

$fh = fopen($faqpage, 'w') or die ("can't open file");  
//okay now let's open our file to prepare it to write
fwrite($fh, json_encode($obj));
fclose($fh);

Upvotes: 0

barell
barell

Reputation: 1489

Your problem is that your logic is incorrect. In the first iteration the ID doesn't match so $newdata will be added. In the second iteration the ID match and the item is going to be updated - but wait. We just added this item in previous iteration! So your loop part should looks like this:

...
$exists = false;
foreach($obj->faqitem as $key => $val)
{
    // update if exists
    if($val->id == $newdata['id']) {
        $val->question = $newdata['question'];
        $exists = true;
    }
}

// add new if not exists
if(!$exists) {
    $newstuff = new stdClass;
    $newstuff->id = $newdata['id'];
    $newstuff->question = $newdata['question'];     
    array_push($obj->faqitem, $newstuff);
}
...

Upvotes: 1

Related Questions