Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

multiple call of User::findById

Hi Everybody, Just started with phalcon and ODM, What I can't understand is the folowing sample

>  $user1 = User::findById(new MongoId('556c639d6cc69be42600002a'));

>  $user2 = User::findById(new MongoId('556c6ee652ce0aa4b9ee58ad'));

>  echo "{$user1->getId()} => {$user1->firstName}<br />";

>  echo "{$user2->getId()} => {$user2->firstName}<br />";

>  die;

The output is

556c6ee652ce0aa4b9ee58ad => User 1

Fatal error: Call to a member function getId() on a non-object in IndexController.php on line 15

Expected:

556c6ee652ce0aa4b9ee58ad => User 1

556c639d6cc69be42600002a => User 2

Both records exist, why 2nd call on same model doesn't give me an object?

I'm testing this on windows 8 machine, with phalcon 2.0.2 and php 5.4.29

User::findById is expecting an integer as its sole argument. You're passing it an object - an instance of MongoId. As a result $user1 and $user2 are probably NULL, rather than an instance of User.

The method just make a findFirst(["_id": mongoId]), is your field called _id? https://github.com/phalcon/cphalcon/blob/2.0.x/phalcon/mvc/collection.zep#L933-L957

Thank You,

Here is the real world sample. Can someone run it and show the output?

I tested this on mac and windows pc, but result is same, php 5.5.25, phalcon 2.0.2, mongo 3.0.3

Mongo Data:

> use testdb
switched to db testdb
> db.users.insert({name: "Oleg"})
WriteResult({ "nInserted" : 1 })
> db.users.insert({name: "James"})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("556ecc523853a3a051cef3a2"), "name" : "Oleg" }
{ "_id" : ObjectId("556ecc6b3853a3a051cef3a3"), "name" : "James" }
>
<?php

use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Url as UrlProvider;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\Collection\Manager as CollectionManager;
use Phalcon\DI\FactoryDefault;
use Phalcon\Events\Manager as EventsManager;

try {
    // Register an autoloader
    $loader = new Loader();
    $loader->registerDirs(array(
        '../app/controllers/',
        '../app/models/'
    ))->register();

    // Create a DI
    $di = new FactoryDefault();
    // Setup the view component
    $di->set('view', function(){
        $view = new View();
        $view->setViewsDir('../app/views/');
        return $view;
    });
    // Setup a base URI so that all generated URIs include the "tutorial" folder
    $di->set('url', function(){
        $url = new UrlProvider();
        $url->setBaseUri('/tutorial/');
        return $url;
    });
    // Simple database connection to localhost
    $di->set('mongo', function() {
        $mongo = new MongoClient();
        return $mongo->selectDB("testdb");
    }, true);
    //Registering the collectionManager service
    $di->set('collectionManager', function() {
        $modelsManager = new CollectionManager();
        return $modelsManager;
    }, true);
    // Handle the request
    $application = new Application($di);
    echo $application->handle()->getContent();
} catch(\Exception $e) {
     echo "PhalconException: ", $e->getMessage();
}
<?php

use Phalcon\Mvc\Collection;

class User extends Collection
{
    public $name;

    public function initialize()
    {
        $this->setSource('users');
    }
}
<?php

use Phalcon\Mvc\Controller;

class IndexController extends Controller
{

    public function indexAction()
    {
        echo "<h1>Hello!</h1>";

        $user1 = User::findById(new MongoId('556ecc523853a3a051cef3a2'));
        $user2 = User::findById(new MongoId('556ecc6b3853a3a051cef3a3'));

        echo $user1->name;
        echo $user2->name;
    }

}

Output:

Hello!
Oleg
Notice: Trying to get property of non-object in /phalcon/app/controllers/IndexController.php on line 16

Yes, it is _id, I added another example

The method just make a findFirst(["_id": mongoId]), is your field called _id? https://github.com/phalcon/cphalcon/blob/2.0.x/phalcon/mvc/collection.zep#L933-L957



33.6k
Accepted
answer

I'm running this small script to reproduce the issue and it works:

<?php

use Phalcon\DI,
    Phalcon\Mvc\Collection,
    Phalcon\Mvc\Collection\Manager as CollectionManager;

$di = new DI();

$mongo = new \MongoClient();
$db = $mongo->selectDB("store");

// Insert sample data
$db->selectCollection("robots")->insert(["name" => "Voltron"]);
$db->selectCollection("robots")->insert(["name" => "Ultron"]);

$di->set('mongo', $db);

$di->set('collectionManager', function() {
    $modelsManager = new CollectionManager();
    return $modelsManager;
}, true);

// Maps to collection "robots"
class Robots extends Collection
{

}

// Accumulate the IDS
$ids = array();
foreach (Robots::find() as $robot) {
    $ids[] = $robot->getId();
}

// Find the ids
foreach ($ids as $id) {
    $robot = Robots::findById(new \MongoId((string) $id));
    echo $robot->name, PHP_EOL;
}
edited Jun '15

It seems I understand the issue now. It is initialize method and setSource

// Maps to collection "the_robots"
class Robots extends Collection
{
    public function initialize()
    {
        $this->setSource("the_robots");
    }
}

The workaround is to use getSource method instead, It seems like a bug though? I will check phalcon sources