Search code examples
phpoopextending-classes

Extending mysqli and using multiple classes


I'm new to PHP oop stuff.

I'm trying to create class database and call other classes from it. Am I doing it the right way?

class database:

class database extends mysqli {

private $classes = array();

public function __construct() {
parent::__construct('localhost', 'root', 'password', 'database');
    if (mysqli_connect_error()) {
    $this->error(mysqli_connect_errno(), mysqli_connect_error());
    }
}

public function __call($class, $args) {
    if (!isset($this->classes[$class])) {
    $class = 'db_'.$class;
    $this->classes[$class] = new $class(); 
    }
return $this->classes[$class];
}

private function error($eNo, $eMsg) {
die ('MySQL error: ('.$eNo.': '.$eMsg);
}

}

class db_users:

class db_users extends database {

public function test() {
echo 'foo';
}

}

and how I'm using it

$db = new database();
$db->users()->test();

Is it the right way or should it be done another way?

Thank you.


Solution

  • You can do it that way, there's nothing wrong with that (I do something similar quite often). The only thing I would suggest is using exceptions instead of die (that way you can safely handle the error)...

    protected function error($eNo, $eMsg, $extra = '') {
        throw new Exception('MySQL error: ['.$eNo.'] '.$eMsg.': '.$extra);
    }
    

    Plus, I'd suggest overloading the query method as well

    public function query($sql, $result_mode = MYSQLI_STORE_RESULT) {
        $result = parent::query($sql, $result_mode);
        if ($result === false) {
             $this->error($this->errno, $this->errstr, $sql);
        }
        return $result;
    }
    

    I'd also suggest storing a copy of the $db object inside of the child class. So:

    class db_users extends database {
        protected $db = null;
    
        public function __construct(Database $db) {
            $this->db = $db;
        }
    
        public function test() {
            echo 'foo';
        }
    }
    

    Then, in __call:

    if (!isset($this->classes[$class])) {
        $class = 'db_'.$class;
        $this->classes[$class] = new $class($this); 
    }