Search code examples
phpjsonormpropelslim

Multi row toJSON function using Propel and Backbone


I'm trying to make what should be a very simple "list all" function using Propel ORM - for Backbone.js to read. This is what I want to do, and in my opinion, should work:

$users = UsersQuery::create()
->find();

echo $users->toJSON();

However, when I'm running that, the results I'm getting are:

{"Users_0":{"Id":1,"EmailAddress":"sdf","Password":"sdf","CreatedAt":null,"ModifiedAt":null},
"Users_1":{"Id":2,"EmailAddress":"dsf","Password":"sdf","CreatedAt":null,"ModifiedAt":null}}

Whilst it's valid JSON, the fact that ever row is an array in the main array is throwing off my JSON. What I need it to return is JSON like this:

[{"Id":1,"EmailAddress":"sdf","Password":"sdf","CreatedAt":null,"ModifiedAt":null},{"Id":2,"EmailAddress":"dsf","Password":"sdf","CreatedAt":null,"ModifiedAt":null}]

I've created the below function (as a test) and it works perfectly, but surely Propel (or Slim, the framework I'm using) has way of stopping everything being inside an array? Here the hack;

$users = UsersQuery::create()
->find();

$json = '[';
foreach($users as $user){
    $json = $json.$user->exportTo('JSON').',';
}
$json = $json.']';
echo str_replace("},]", "}]", $json);

Any help would be greatly appreciated! Thanks all.


Solution

  • I hate to say it, but I think this is just one of those "that's how Propel works" situations. That said, you could improve your helper function a little to be more robust.

    I would put this code in your UserQuery class:

    class UsersQuery extends BaseUsersQuery {
      ...
    
      public function toJSONArray() {
        $users = $this->find();
        $userArray = array();
        foreach($users as $user){
          array_push($userArray, $user->toArray());
        }
        return json_encode($userArray);
      }
    }
    

    And then use it like so...

    $userJSON = UsersQuery::create()->toJSONArray();
    

    Or if you have other criteria...

    $userJSON = UsersQuery::create()
                  ->filterBySomeField("someValue")
                  // other Criteria ...
                  ->toJSONArray();