Framework: json_encode returning false

Created on 27 Apr 2016  路  24Comments  路  Source: laravel/framework

Hi, im using

PHP 7.0.4-7ubuntu2 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

And
Laravel Framework version 5.1.34 (LTS)

When giving the below value to json_encode it is returning false rather than string

Illuminate\Database\Eloquent\Collection {#3502
     all: [
       App\User {#3487
         last_active: "",
       },
     ],
   }

but it is returning correct string in php5-fpm.

two days back only i upgraded to php7 and observed this error.

Most helpful comment

As a workround, you can use json_encode($obj->jsonSerialize()) instead of json_encode($obj).
or you may modify the Illuminate\Support\Collection->jsonSerialize() to the following codes:

$res = array_map(function ($value) {
    if ($value instanceof JsonSerializable) {
        return $value->jsonSerialize();
    } elseif ($value instanceof Jsonable) {
        return json_decode($value->toJson(), true);
    } elseif ($value instanceof Arrayable) {
        return $value->toArray();
    } else {
        return $value;
    }
}, $this->items);
json_encode([]); //clear the json_last_error
return $res;

All 24 comments

Please report this bug to the PHP team.

The error occurred in Collection class that is specific to laravel rather than PHP team. Im not sure the PHP team is aware of Collection class and its magic methods.

If it worked on PHP 5, and is broken on PHP 7, this is a bug. They did not intend for the json functions to have changed between versions.

Try json_last_error_msg first

Hi @rkgrep , the output is "Syntax error"

@pavankumarkatakam are you sure that json_encode returns that error?
here is a comment on PHP 7 about it, but for json_decode

@pavankumarkatakam do you have JSON casts in the model?

Hi @rkgrep , I have casts enabled in User model, shown below

 protected $casts = [
        'privileges' => 'json',
        'preferences' => 'json',
        'access' => 'json',
        'last_active' => 'json',
        'id' => 'integer',
        'family_data_id' => 'integer',
        'mobile_verified' => 'boolean',
        'email_verified' => 'boolean',
        'mobile' => 'integer',
        'is_delete' => 'boolean',
        'app_storage' => 'json',
        'custom_data' => 'json'
    ];

And mentioning about the column last_active.

Hi @rkgrep , when issuing the command json_encode(["something"=>""]); it returns correct string "{"something":""}" , but when using the Collection item with empty string value it is returning the false.

Collection item in my case

Illuminate\Database\Eloquent\Collection {#3465
     all: [
       App\User {#3466
         last_active: "",
       },
     ],
   }

Which is resulted from my query $temp=\App\User::where('id',3)->select('last_active')->get(); .

I hope its clear now. That's the reason i have opened issue here rather than the PHP bug.

@pavankumarkatakam Collection is being converted to array first. With each item converted to array.
What does $collection->toArray() return?

The output when converted to toArray() ,

[
     [
       "last_active" => null,
       "age" => null,
       "age_display" => null,
       "religion_display" => "",
       "country_display" => "",
       "country_code_display" => null,
     ],
   ]

If the give above input to json_encode it is working fine. shown below
"{"something":[{"last_active":null,"age":null,"age_display":null,"religion_display":"","country_display":"","country_code_display":null}]}"

When explicitly specifying the toArray() on query result (Collection) it is working fine

json_encode(["something"=>\App\User::where('id',2)->select('last_active')->get()->toArray()]);

it returning the "{"something":[{"last_active":null,"age":null,"age_display":null,"religion_display":"","country_display":"","country_code_display":null}]}"

But in my applications (roughly 7 to 8 ) projects i have used to return Collection items in response in many places, i think i want to check all of them and write toArray(); its really a big change i think so.

I think it's related the php bug 72069. If a class implementing JsonSerializable calls json_encode/json_decode in jsonSerialize, and that function fails then it will lead to the failure of encoding the object.

You can try if the latest version from git fix this bug or not.

As a workround, you can use json_encode($obj->jsonSerialize()) instead of json_encode($obj).
or you may modify the Illuminate\Support\Collection->jsonSerialize() to the following codes:

$res = array_map(function ($value) {
    if ($value instanceof JsonSerializable) {
        return $value->jsonSerialize();
    } elseif ($value instanceof Jsonable) {
        return json_decode($value->toJson(), true);
    } elseif ($value instanceof Arrayable) {
        return $value->toArray();
    } else {
        return $value;
    }
}, $this->items);
json_encode([]); //clear the json_last_error
return $res;

Hi @jhdxr , first i installed PHP 7.0.5

PHP 7.0.5-3+donate.sury.org~xenial+1 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

But still the problem exists, after that i changed the Collection class jsonSerialize() function, then its working fine.

@pavankumarkatakam the bug was fixed 4 days age and not released yet. You have to compile the source from git on you own, or you may be have to wait for 7.0.7 out (as 7.0.6 is at rc stage)

Actually im not aware of compiling, so i go with fix in collection for now.

And Thanks for helping.

Hi @jhdxr, if we go with the fix we want to change in all code where there is json_encode(), so i want to compile myself the php, could you please give me instructions to do so.

@pavankumarkatakam Did you change the actual implementation of the jsonSerialize function in the laravel framework core? If you did, then its bad practice. I would suggest creating a simple class to set JSON data. What @jhdxr provided you was the right solution but you shouldn't be changing the core framework code.

I myself am using PHP 7 for one of my side projects. I haven't run into the issue you mentioned.

Hi @srmklive , this is already a bug in the php repo and fixed in the php 7.0.7 version. So im closing it.

Today i installed the php 7.0.7 and this is fixed

Hi @pavankumarkatakam
You said this fixed in 7.0.7 ... I have this issue for 7.0.11 !!!

Well I don't know regarding 7.0.11 , may be they changed want to check in php language repository.

I have the same issue with PHP 5.6.31:

    $users = Users::all();
    return Response::json($users);
 The Response content must be a string or object implementing __toString(), "boolean" given. 

False appears when toJson() is called.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iivanov2 picture iivanov2  路  3Comments

Anahkiasen picture Anahkiasen  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

digirew picture digirew  路  3Comments

gabriellimo picture gabriellimo  路  3Comments