We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

ODM returning arrays instead of objects.

Using Phalcon 2.0.11 with a Mongo database, ::find returns arrays and not objects as I expected.

In the mongo shell I create a document with a few objects, e.g.

>db.flints.insert({name:"test", "stuff" : { "enabled" : true, "info" : { "description" : "Descrip" }}})
WriteResult({ "nInserted" : 1 })
> db.flints.find({name:"test"})
{ "_id" : ObjectId("573dccf0f6a6ce56e20ebe56"), "name" : "test", "stuff" : { "enabled" : true, "info" : { "description" : "Descrip" } } }

However using the following code snippet the properties enabled, info, description etc. are only accessible via array notation.

$flint = Flints::findFirst(array(array('name'=>'test')));
echo $flint->stuff->info->description;      //  PHP Notice:  Trying to get property of non-object
echo $flint->stuff['info']['description'];  //  Prints 'Descrip'
$flint->stuff->enabled = false;             //  PHP Warning:  Attempt to assign property of non-object
$flint->stuff['enabled'] = false;
$flint->save();

Is there a way to access the returned document by using properties instead of arrays ?

Thanks.

My model, and services,

use Phalcon\Mvc\Collection;
class Flints extends Collection { }
$di->setShared('mongo', function () use ($config) {
    $mongo = new MongoClient();
    return $mongo->selectDB("test");
});

$di->set('collectionManager', function() {
    return new Phalcon\Mvc\Collection\Manager();
}, true);
edited May '16

PDO has an options to set fetch mode: $result->setFetchMode(Phalcon\Db::FETCH_OBJ);

https://docs.phalcon.io/en/latest/api/Phalcon_Db_Result_Pdo.html

Find() and findFirst() methods return resultset as: return static::_getResultset(parameters, collection, connection, true);

/**
     * Returns a collection resultset
     *
     * @param array params
     * @param \Phalcon\Mvc\Collection collection
     * @param \MongoDb connection
     * @param boolean unique
     * @return array
     */

Additionally,

Every instance of a model represents a document in the collection. You can easily access collection data by reading object properties. For example, for a collection “robots” with the documents:

https://docs.phalcon.io/en/latest/reference/odm.html#understanding-documents-to-objects



1.0k

I don't think there is the equivalent of PDO's fetch mode for Mongo databases. I'm using the ODM not ORM.

find() is returning my JSON document, but I can only access the first level properties, anything deeper has been coalesced into an array.

E.g. Using the example data inserted in mongo above,

php > $x=json_decode('{"name" : "test", "stuff" : { "enabled" : false, "info" : { "description" : "Descrip" } } }');
php > var_dump($x);
object(stdClass)#1 (2) {
  ["name"]=>
  string(4) "test"
  ["stuff"]=>
  object(stdClass)#2 (2) {
    ["enabled"]=>
    bool(false)
    ["info"]=>
    object(stdClass)#3 (1) {
      ["description"]=>
      string(7) "Descrip"
    }
  }
}

shows everyting as an object. A var_dump() of the result set from find() shows enabled, info etc. as arrays. I can access $flint->name (like robots) but not an extra level down.

edited May '16

I know, I just posted how it is done via PDO and RDBMS.

For MongoDB, I would expect ODM to return objects. And now you made a clarification - it does return as an array of objects, it's just that you cannot access it when it's multidimensional array. That's PHP core thing I'm afraid.