Search code examples
phpjsonexplode

How to overwrite file by changing json in it?


I have a file test.json with json content like below -

{"user_id":3,"created_at":"2020-10-05 04:59:05","expire_user_id":"2,1"}

After reading above json I need to rewrite it like below.

{"user_id":2,"created_at":"2020-10-05 04:59:05","expire_user_id":"1"}

Another example. For below json -

{"user_id":3,"created_at":"2020-10-05 04:59:05","expire_user_id":"1"}

I need to make it like this -

{"user_id":1,"created_at":"2020-10-05 04:59:05"}
  • Idea is to get first number from expire_user_id key and put it inside user_id key.
  • If expire_user_id only has one element in it, then after removing that element, final json should not have that key in it.
  • If there is no value inside expire_user_id key or expire_user_id key is not present then I want to rewrite it with empty string.

Below is what I have tried:

$data = json_decode(file_get_contents('test.json'));
if ((int) $data->user_id === $_SESSION['user_id']) {
    // rewrite the file with above logic.
    $content = isset($data->expire_user_id)
               ? json_encode(['user_id' => explode(',', $data->expire_user_id)[0], 'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s')])
               : '';
    file_put_contents('test.json', $content);
}

I tried with above logic where I am using explode to get first value of comma separated string but confuse on how to put remaining string in expire_user_id key back or don't put it back if there is only one element in it. Above code doesn't work currently as confuse on how to put other things back in that json.


Solution

  • You could use the following function (which you should rename to something more accurate). What it does is:

    • json_decode the JSON,
    • if expire_user_id is empty, return '{}' (empty object), otherwise:
      • explode expire_user_id into an array,
      • removes the first user ID using array_shift,
      • puts that it into user_id,
      • unsets expire_user_id if there are no more values in it,
      • joins it back with commas using implode otherwise,
    • return the re-json_encoded data.

    Code:

    /**
     * @throws JsonException
     */
    function alterJson(string $json): string
    {
        $data = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
    
        if (empty($data->expire_user_id)) {
            return '{}';
        }
    
        $data->expire_user_id = explode(',', $data->expire_user_id);
        $data->user_id = array_shift($data->expire_user_id);
    
        if ($data->expire_user_id) {
            $data->expire_user_id = implode(',', $data->expire_user_id);
        } else {
            unset($data->expire_user_id);
        }
    
        return json_encode($data, JSON_THROW_ON_ERROR);
    }
    

    Usage:

    $alteredJson = alterJson(<<<JSON
        {"user_id":3,"created_at":"2020-10-05 04:59:05","expire_user_id":"2,1"}
    JSON);
    

    Demo