Framework: Input::json should not convert object to array

Created on 27 Feb 2013  Â·  10Comments  Â·  Source: laravel/framework

When trying to pass around an object, Input::json() returns an array instead. When the request payload contains the following JSON object:

{"name":"John", "age":30}

The expected behavior should be:

$person = Input::json();
$person->name; // doesn't work

Instead each object property must be accessed as an array:

$person = Input::json();
$person['name'];

This used to work fine before the array_get call added somewhere around cd9fcd06.

Most helpful comment

@bencorlett

There is nothing that makes StdClass more appropriate to map "javascript objects" than an associative array does in PHP. Arrays are much nicer.

Not true, this wrecks empty objects:

json_encode(json_decode('{}')); // '{}'
json_encode(json_decode('{}', true)); // '[]'

I'm sorry to reply to a 4 year old post, but this sort of horrible misconception really ruins the integrity of JSON data and makes my life hell when PHP devs do this with reckless abandon.

All 10 comments

This has nothing to do with the array_get call, but the second argument to json_decode. This has been changed to true to get an associative array instead of an object, because then we can easily select a key with array_get.

There is no way really to do something about this for everyone. If you really want an object, do a cast or simply override Input::json (the class behind the facade, then set subclasses instance in the app container) to roll you own implementation.

I much prefer how it is now.

Yeah, just do $person = (object) Input::json();

The above proposed solution only works for simple objects. For the following nested object:

{'person': {'name':'John', 'age':30, 'address': {'zip':12345,'state':'CA'} } }

...the only strategy is to recursively convert the inner-most objects and then construct the parent object. Right now I am sending objects in one end and getting associative arrays out the other which becomes annoying.

There is nothing that makes StdClass more appropriate to map "javascript objects" than an associative array does in PHP. Arrays are much nicer.

Have a geez out there for something to recursively convert to StdClass should you really require it. It seems more consistent to use arrays here than StdClass.

On 28/02/2013, at 4:33 PM, aleemb [email protected] wrote:

The above proposed solution only works for simple objects. For the following nested object:

{'person': {'name':'John', 'age':30, 'address': {'zip':12345,'state':'CA'} } }
...the only strategy is to do recursively convert the inner-most objects and then construct the parent object. Right now I am sending objects in one and and getting associative arrays out the other which becomes annoying.

—
Reply to this email directly or view it on GitHub.

The problem is I'd like to be able to simulate the data that I get when I'm pulling records from a database. With results from the database, I can use the object->property notation, but apparently Laravel is having problems letting me pass data to templates when I convert an array to an object (using the code shown below):

class T {
  public static function arrayToObject($array){
    return json_decode(json_encode($array));
  }
}

Then, when I do this in my Laravel controller:

$data = T::arrayToObject($data);
return View::make('blade-template')->with($data);

I get this error: Illegal offset type

And when I try this in Laravel controller:

$data = T::arrayToObject($data);
return View::make('blade-template',$data);

I get this error: array_merge(): Argument #2 is not an array

Any suggestions?

I'd definitely prefer to use object notation instead of arrays in my templates.

Thank you in advance for taking the time to look at this... I appreciate all of your help!

@bencorlett

There is nothing that makes StdClass more appropriate to map "javascript objects" than an associative array does in PHP. Arrays are much nicer.

Not true, this wrecks empty objects:

json_encode(json_decode('{}')); // '{}'
json_encode(json_decode('{}', true)); // '[]'

I'm sorry to reply to a 4 year old post, but this sort of horrible misconception really ruins the integrity of JSON data and makes my life hell when PHP devs do this with reckless abandon.

Nice work, good edge case.

The mainly problem here is you are assuming one or other way works for everyone, limiting the flexibility and providing a tool that we must tweak in order to cover base cases in API concept.

{} and [] are valid values and different structures in json format.

{}: empty object
[]: empty array / collection

I think to store them in a Documents DB make sense, and to use a Documents DB on laravel is possible, so...

Wont be more flexible to do not force the json_decode with true and allow users to decide by config option or something like that?

Why this issue is closed? I need to save very a complex json object (wysiwig internal representation) as JSON field in DB. Currently Laravel casts {} into [] and '' into null, breaking my wysiwig when I get transformed JSON back.

I know that php is dynamic language, but so is JS, and changing object structure without programmer's knowledge because this is convenient is just plainly irresponsible.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shopblocks picture shopblocks  Â·  3Comments

klimentLambevski picture klimentLambevski  Â·  3Comments

iivanov2 picture iivanov2  Â·  3Comments

PhiloNL picture PhiloNL  Â·  3Comments

digirew picture digirew  Â·  3Comments