12

In Laravel 5.5

Route::get('/test2', function (){
    $data = (object) [];

    return response()->json($data);

});

it always returns [] rather than {}.


another code:

Route::get('/test2', function (){
    $data = (object) [];

    return json_encode($data);

});

it correctly returns {}


I want to use response()->json() helper to return empty object instead of empty array, is it possible?

kingshark
  • 315
  • 1
  • 2
  • 11
  • Possible duplicate of [How to define an empty object in PHP](https://stackoverflow.com/questions/1434368/how-to-define-an-empty-object-in-php) – DrNio May 01 '18 at 08:27
  • @DrNio not the same problem. see my code, already defined a object data, but problem is using response() -> json() always return empty array for the data. – kingshark May 01 '18 at 08:42
  • 1
    Hmm your first variant should be ok as well since by default it uses the `json_encode`. Unless your `ResponseFactory` does not return the default `JsonResponse`. Could you try this: `return response()->json($data, 200, [], JSON_FORCE_OBJECT);` – vstm May 01 '18 at 08:44

6 Answers6

14

This works:

return response()->json(new stdClass());
Hamid Mohayeji
  • 3,977
  • 3
  • 43
  • 55
4

One more example, inspired by Hamid Mohayeji answer:

return \response()->json(null);

No need to instantiate stdClass (memory allocation though).

Tarasovych
  • 2,228
  • 3
  • 19
  • 51
4

This works in Laravel 5.6

Route::get('/test2', function (){
    $data = (object) [];

    return response()->json($data, 200, [], JSON_FORCE_OBJECT);

});
bloody numen
  • 487
  • 6
  • 13
2

Using dingo/api modifies the answer of the empty array as @kingshark said, but you can make this work without stoping using dingo or modifying anything else than your own response.

Dingo expects the $data to be already encoded as json, so, if you do:

$data = ['message' => 'Lorem Ipsum', 
         'errors' => []];
return response()->json($data);

Will get:

{
    "message": "Lorem Ipsum",
    "errors": []
}

But if you do:

$data = ['message' => 'Lorem Ipsum', 
         'errors' => []];
$data = json_encode($data, JSON_FORCE_OBJECT);
return response()->json($data);

You will get:

{
    "message": "Lorem Ipsum",
    "errors": {}
}
buzkall
  • 927
  • 11
  • 14
1

When you return response()->json($data), it returns a JsonResponse object which includes $data in data field. So when you receive this response, you get the data with the same format(object).

JsonResponse json(string|array $data = [], int $status = 200, array $headers = [], int $options)

When you return json_encode($data), it will parse the $data and returns a string: "{}". Only if you decode "{}", it will become object again.

string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )

Stephen
  • 3,822
  • 2
  • 25
  • 45
-1

Thanks everyone, finally I found the problem: dingo/api.

If I use response()->json($data) in app using dingo/api package, there is a different response handling process. At some point, it will go through \Dingo\Api\Http\Response::makeFromJson method which decode the response content, then create a new response instance, which changed {} to [].

If I removed or do not use dingo/api package, response()->json() can work well, at least in Laravel 5.5.

dingo/api override, change and extend large amount of laravel built-in classes and approach in the entire request life cycle, from route to response to exception handling.

kingshark
  • 315
  • 1
  • 2
  • 11