Mongodb-odm: Uncaught Error: Call to a member function add() on boolean $loader

Created on 12 Mar 2019  路  13Comments  路  Source: doctrine/mongodb-odm

| Q | A
|------------ | -----
| Version | 2.0 beta

Support Question

I'm trying to set up doctrine on my yii2 project, but I keep getting the error Fatal error: Uncaught Error: Call to a member function add() on boolean where the code runs $loader->add('Documents', __DIR__);

bootstrap.php file (in __DIR__/common/config/bootstrap.php):

<?php

Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('Documents', dirname(dirname(__DIR__)) . '/documents');

use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\ODM\MongoDB\Configuration;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;

if ( ! file_exists($file = 'C:/path/to/vendor/autoload.php')) {
    throw new RuntimeException('Install dependencies to run this script.');
}

$loader = require_once $file;
$loader->add('Documents', __DIR__);

AnnotationRegistry::registerLoader([$loader, 'loadClass']);

$config = new Configuration();
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir(__DIR__ . '/Hydrators');
$config->setHydratorNamespace('Hydrators');
$config->setDefaultDB('fsa');
$config->setMetadataDriverImpl(AnnotationDriver::create(__DIR__ . '/Documents'));

$dm = DocumentManager::create(null, $config);

I cannot figure out what is wrong; if $loader was a boolean then why would the docs say to set $loader = require_once $file;?

Thanks

Question

All 13 comments

By default, the composer autoload file returns the autoloader in question, which seems to not be the case for you. Could you tell us which version of composer you are running locally?

I'm using composer version 1.8.0.

Maybe this is related to the problem? When I run

if ( ! file_exists($file = __DIR__.'/vendor/autoload.php')) {
    throw new RuntimeException('Install dependencies to run this script.');
}

rather than

if ( ! file_exists($file = 'C:/path/to/vendor/autoload.php')) {
    throw new RuntimeException('Install dependencies to run this script.');
}

the program gets stuck on this line rather than on $loader->add().

I missed this initially, but if your bootstrap file is located in /common/config/bootstrap.php you'll want to use this:

if ( ! file_exists($file = __DIR__.'/../../vendor/autoload.php')) {

In general, you'll want to ensure that you're actually loading the autoload file from the vendor directory. Not knowing your path structure I can only guess where this is, but it should be easy to handle.

Thanks - __DIR__ works now. I still get the "uncaught error" though.

@alcaeus Does this mean I need to autoload the files manually? How is that supposed to be done?

Sorry for the long delay, I was unable to do any work for personal reasons.

I see that the answers on your StackOverflow post pretty much cover what I was going to ask next, so we can skip that step. Can you confirm that your autoload.php file is a) the correct file you intend to load and b) that it contains a return statement? Thanks!

Yes, it looks like:

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit[longstring]::getLoader();

@klickers Pleas set a breakpoint in autoload_real.php and try to debug it that way. Took me a while, but the issue is most likely that your autoload file is returned twice. Take this example:

// include.php
<?php

return 'foo';

Then, try to include it twice:

php > var_dump(require_once 'include.php');
php shell code:1:
string(3) "foo"
php > var_dump(require_once 'include.php');
php shell code:1:
bool(true)

As you can see, all calls to require_once after the initial call no longer return the value returned by the script (in your case the autoloader) but true. This corresponds with your error message. You'll have to figure out what causes the autoloader script to be included twice and work around it.

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.

@klickers Any luck with my suggestion above?

@alcaeus I'm so sorry for the late reply; I got too busy and didn't have much time to work on this project for a while. I just figured out where it's been double-called; the framework I'm using calls autoloader.php itself. So my bootstrap.php, which was loaded after the main file of the framework, called it a second time and returned bool(true).

Thank you so much for your time and help! I really appreciate it. 馃槂 Sorry I was so late in getting back.

Was this page helpful?
0 / 5 - 0 ratings