Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input::json should not convert object to array #443

Closed
aleemb opened this issue Feb 27, 2013 · 12 comments
Closed

Input::json should not convert object to array #443

aleemb opened this issue Feb 27, 2013 · 12 comments

Comments

@aleemb
Copy link

aleemb commented Feb 27, 2013

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 cd9fcd0.

@JoostK
Copy link
Contributor

JoostK commented Feb 27, 2013

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.

@bencorlett
Copy link
Contributor

I much prefer how it is now.

@taylorotwell
Copy link
Member

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

@aleemb
Copy link
Author

aleemb commented Feb 28, 2013

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.

@bencorlett
Copy link
Contributor

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.

@hughsmith10
Copy link

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!

@vdh
Copy link

vdh commented Feb 17, 2017

@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.

@bencorlett
Copy link
Contributor

Nice work, good edge case.

@ruudy-es
Copy link

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?

@klis87
Copy link

klis87 commented Sep 3, 2018

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.

@davidvalen95
Copy link

knew that this old post, but i just stumbled in this problem.
solution:
we can retrieve true JSON from the request with this method
$json = json_decode($request->getContent(),**false**); default for second argument is false but just to emphasize on it

explanation:
the $request->getContent() is giving raw request body thus, a correct syntax of encoded_json can be decoded with json_decode

@sbaum2s
Copy link

sbaum2s commented Nov 13, 2024

knew that this old post, but i just stumbled in this problem. solution: we can retrieve true JSON from the request with this method $json = json_decode($request->getContent(),**false**); default for second argument is false but just to emphasize on it

explanation: the $request->getContent() is giving raw request body thus, a correct syntax of encoded_json can be decoded with json_decode

Perfect. The other solutions around arrays...its cleaner to work with object->property notation than with quotes...and its totally annnoying to move back and forth between array notation and object notation. That way its not possible to deliver clean code / professional work. PHP 8 and Laravel are to some degree object oriented and type save, but than we have non-configurable conversion of objects to arrays in core components?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants