Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: "Call to undefined method" ... but method is defined?

I have a class Database.php, which is an abstract Singleton class:

<?php

abstract class Database
{
    protected static $_instance;
    ...

    public static function instance()
    {
        $class = get_called_class();

        if (!self::$_instance) {
            self::$_instance = new $class();
        }

        return self::$_instance;
    }
}

?>

Other databases extend this class and implement the abstract functions, so that I can change the database I use, while making sure my application still works as long as it uses the functions in this abstraction layer (I have left out the function definitions from the above code).

I have a class PDO, in PDO.php. It extends database and also includes the instance() function identical to the one above, but it does not have it's own $_instance variable.

class PDO extends Database
{
    //...

    public static function instance()
    {
        $class = get_called_class();

        if (!self::$_instance) {
                self::$_instance = new $class();
        }

        return self::$_instance;
    }
}

Originally I thought I wouldn't have to include the instance() function in the PDO class, since it inherits from Database. But I included it because I was getting this error:

Fatal error: Call to undefined method PDO::instance()

The problem is that I'm still getting this error, even with the code above. I don't know if this is related, but there is another strange error I was getting. The type of database I want to use, in this case PDO, is stored in a variable accessible through App::setting('DB'). The Model base class in my MVC framework loads the appropriate database class and stores it in $this->_db. Here is the code for the Model:

<?php

require_once 'Databases/Database.php';

class Model
{
    protected $_db;

    public function __construct()
    {
        $database = App::setting('DB'); // 'PDO' 
        require_once 'Databases/' . $database . '.php';
        $this->_db = $database::instance(); // this is what triggers the error
    }
}

?>

Now this code was giving me an error that I could not redeclare the PDO class. I searched online, and found that the problem is usually related to using include() instead of require_once(). I checked everywhere and my Autoloader, didn't see any include(). Even with require_once() in the model above, it was still giving me the error (this is the only place I was requiring the PDO class...).

To fix that error, I am using a band-aid solution where I replace the require in the Model constructor with:

if (!class_exists($database)) {
    require_once 'Databases/' . $database . '.php';
}

Can anyone explain what is going on here?

like image 531
Logan Serman Avatar asked Apr 07 '26 16:04

Logan Serman


1 Answers

The class name PDO is a standard class of PHP, so with your solution to include your PDO class you are actually never including yours.

like image 67
enricog Avatar answered Apr 09 '26 05:04

enricog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!