Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
REST controller with json - empty output!
  • Hi, I'm having trouble outputting json with a REST controller. Here's some code:
    class Controller_API extends Controller_Rest {
    
        public function get_list()
        {
            $users = Model_User::find('all');
    //print_r($users)
            $this->response($users);
            
        }
    }
    
    This will output:
    {
    
        1: { }
        2: { }
    
    }
    
    I have two users in my test environment, so having 2 json values would be correct, but they're empty.
    By uncommenting the print_r I get my 2 results so the $users variable is correct. Also, User is a ORM Model, generated with scaffolding. Thanks
  • Phil, first of all: I'm not sure whether to answer here or on github... Arjen, I tried your solution. It works partially:
     $users = Model_User::find('all', array('related' => array('votes')));
     //print_r($users);
     $users = Format::factory($users)->to_array();
     $this->response($users);
    
    This will output $users correctly, but without votes.
    Uncommenting the print_r shows votes correctly (I set up Orm Relations). Thanks :)
  • Hey guys, I updated the Orm\Model today. Now its ArrayAccess implementation will return the loaded relations as well. And there's a new method for casting the model to an array:
    $model = Model_Example::find(1);
    $array = $model->to_array();
    
  • Nice. I'll give that a shot next week. Great support guys.
  • What does your models look like?
  • Hi, The response is expecting and array and you are sending it Model_User object. From the manual
    response($data = array(), $http_code = 200)
    

    You need to do something like a
    foreach($users as $user)
    {
      // Build your array here before sending it on
    }
    
    Phil.
  • Right...
    Could you please elaborate on the array building bit?
    You mean I have to create an array with each property?
    Ex.
    $u_response = array();
    foreach ($users as $user) {
    $my_user['name'] = $user->name;
    $my_user['nickname'] = $user->nickname;
     array_push($u_response,$my_user);
    }
    

    Thanks
  • Hi guys. I have a question about this also. This doesn't seem to work as expected. When you try to get the above output as an XML it neatly returns a proper XML with the object's values. But when using JSON as output format it simply won't output the data. Why would you have to iterate and save a reference array for a JSON output but not for XML output? Thanks :)
  • Hmm maybe you don't have to build the array then. post your controller code. I looked at the class core/classes/controller/rest.php This class basically sets the header type and in the case of a json request format it simply returns a json encoded string for whatever data you passed to it this class will return something even if the format is not supported unless it's response status is set to 404 which returns nothing. Phil.
  • Phil, Arjen is right. I tried the same exact code I originally posted, but changed config/rest.php back to xml.
    The output is correct, an xml document with everything I need. I guess there's a bug with the JSON Output.
    I looked at core/classes/controller/rest.php, too. The json output simply calls json_encode, so I guess there's a problem with the conversion from ORM/Model to JSON...
  • Not at my pc at the moment so can't check the class and this may sound like a silly question but I came across a case sensitive thing a while ago but can't remember where as it's been fixed now are you using a local app/config/rest.php as I can't remember it checking for that and are you entering lowercase json? I always build an array before I json encode hence the suggestion but guess your right you have potentially found a bug. Phil.
  • Yes, it is lowercase. Anyway, I tried this, too:
    public function get_list()
        {
      $users = Model_User::find('all');
      echo json_encode($users);
        }
    

    And I get the same empty output. So it's a ORM to JSON thing...? (I can't get the formatting button to work on this forum...using Firefox 4).
  • koichirose, Don't worry I can't get any of the formating buttons to work either and I am using Chrome have to type everything in. Can you please report the issue here http://dev.fuelphp.com/ so the dev team can pick it up for you. Phil.
  • Looks to me like it's a problem with the ORM indeed. Just using encode_json doesn't seem to suffice. But I just started with Fuel today ;)
  • Just a small question after looking at the code. Wouldn't it be better by using the Format class for outputting specific formats (such as JSON)? Right now the REST controller does the encoding. By the way, if you need to get the JSON output to work properly right now you can use the following code: format.php (core/classes) line 84 replace:
    foreach ((array) $data as $key => $value)
    

    with:
    foreach ($data as $key => $value)
    

    And use the following code in the REST controller for JSON output:
      $blogs = Model_Blog::find('all');
      $blogs = Format::factory($blogs)->to_array();
      $this->response($blogs);
    

    This basically forces the model into a readable array output. This is a pretty nasty fix, I can definitely come up with something better with more time. But I'll leave that up to the developers! :)
  • Right you are! When you pass an entire result from ORM to REST it is not just passing the data but all the other gumph that goes with it. By using this Format::to_array() method we can avoid this issue, but it not only has overhead it could lead to messing up data. That said, if this solution works (can somebody confirm it) I might just make everything going into response() format through an array first, just to clear out the crap.
  • I had the same issue with output on the Controller_Rest I can confirm the to_array casting works
  • Just wanted to let you know that there is a new Interface in PHP 5.4+ for this.

    http://php.net/manual/en/class.jsonserializable.php

    It works like this:

    class ClassToSerialize implements JsonSerializable
    {
    private $foo = 42; // <-- normaly not serializable
    private $bar = 23; // <-- normaly not serializable

    public
    function JsonSerialize() {
    return array(
    'foo'
    => $this->foo,
    'bar'
    => $this->bar
    );
    }
    }

    $json = json_encode(new ClassToSerialize()) // output => {"foo":42, "bar": 23}

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion