Hi
I get this error in SimpleTest when trying to use the DI container Bucket. I used code that is very similar to the examples shown at http://github.com/troelskn/bucket under “instantiate a class”:
Fatal error: Uncaught exception 'LogicException' with message
'Class Auth could not be loaded' in
/path/to/bucket/bucket.inc.php:111 Stack trace:
#0 [internal function]: spl_autoload('Auth')
#1 /path/to/bucket/bucket.inc.php(111): spl_autoload_call('Auth')
#2 /path/to/bucket/bucket.inc.php(92):
bucket_Container->createThroughReflection('Auth')
#3 /path/to/autentication/auth.php(19):
bucket_Container->create('Auth')
#4 /path/to/tests/auth_test.php(5): require_once('/var/www/authen...')
#5 {main} thrown in /path/to/bucket/bucket.inc.php on line 111
Here is the code:
<?php
require_once("bucket.inc.php");
class DbFactory{
private $db;
function __construct(){
return new PDO("mysql:host=localhost;dbname=users", "user", "secret");
}
}
class Auth{
private $db;
function __construct(DbFactory $db){
$this->db = $db;
}
}
$auth_container = new bucket_Container();
$auth = $auth_container->create('Auth');
?>
This is my first time using a DI container. I am not sure how Bucket can determine where the Auth class is located, which appears to be the problem? Can you see why this error is being thrown?
Your help is appreciated.
Thanks,
Steve
As it was throwing an error about spl_autoload_call, I put the code in separate files under the same folder as bucket.inc.php. These are the separate files code:
Auth Class:
<?php
class Auth{
private $db;
function __construct(DbFactory $db){
$this->db = $db;
}
}
?>
DbFactory Class:
<?php
class DbFactory{
function __construct(){
return new PDO("mysql:host=localhost;dbname=users", "user", "secret");
}
}
?>
Bootstrap File:
<?php
require_once("bucket.inc.php");
$auth_container = new bucket_Container();
$auth = $auth_container->create("Auth");
?>
The New Error:
Fatal error:
Uncaught exception 'ReflectionException'
with message 'Class DbFactory does not exist'
in /path/to/bucket.inc.php:133 Stack trace:
#0 /path/to/bucket.inc.php(133):
ReflectionParameter->getClass()
#1 /path/to/bucket.inc.php(92):
bucket_Container->createThroughReflection('Auth')
#2 /path/to/auth_bootstrap.php(4):
bucket_Container->create('Auth')
#3 {main} thrown in
/path/to/bucket.inc.php on line 133
That’s an error. I have never tested it without an autoload function installed. I’ve submitted a patch to the repo that fixes it.
Hi kyberfabrikken,
Thanks, I will get this from the repos. By the way what do you mean by
I have never tested it without an autoload function installed
Regards,
Steve
I downloaded the new bucket.inc.php file from GIT, but I still get an exception thrown:
Fatal error:
Uncaught exception 'bucket_CreationException'
with message 'Undefined class Auth' in
/path/to/bucket.inc.php:112 Stack trace:
#0 /path/to/bucket.inc.php(92):
bucket_Container->createThroughReflection('Auth')
#1 /path/to/auth_bootstrap.php(4):
bucket_Container->create('Auth')
#2 {main} thrown in
/path/to/bucket.inc.php on line 112
Here are the files/classes again:
auth.php - Class Auth:
<?php
class Auth{
private $db;
function __construct(DbFactory $db){
$this->db = $db;
}
}
?>
DbFactory.php - Class DbFactory:
<?php
class DbFactory{
function __construct(){
return new PDO("mysql:host=localhost;dbname=users", "user", "password");
}
}
?>
auth_bootstrap.php
<?php
require_once("bucket.inc.php");
$auth_container = new bucket_Container();
$auth = $auth_container->create("Auth");
?>
PHP has a feature called autoload, whereby it can trigger a userland function (__autoload) when a class that is referenced doesn’t exist. Bucket triggerede this function explicitly, and apparently that causes problems when there is no such function defined (As is the case in your example). I never realised that problem existed, because I have never tried to use bucket in an application where I didn’t also define an autoload function.
The reason why you’re having trouble now is more mundane. From your second post i assume that you have put the various classes into separate files. If you do so, you need an autoload function or you need to explicitly require them. Bucket will not load any classes - it will merely trigger whatever class loader has been installed. If you go back to your original example, it’ll work too.
Ok,
Thank you… Given what you said it seems defining an autoload function would be the way to go.
Regards,
Steve
Yes - for any non-trivial-sized application, an autoloader is very useful. You can simply install the default spl_autoload by calling [FPHP]spl_autoload_register[/FPHP]
Thank you… works like a charm!
Regards,
Steve