How to connect MYSQL database to other classes through constructor [duplicate]

Trying to get to hang of PDO but not having much fun at the moment. I bet it's something really simple as well.

EDIT: What would be a better way to go about doing this? i.e instead of wrapping it in a class?

classes/DB.class.php:

<?php

// DB.class.php

class DB {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    // Establish Connection to Database.

    public function connect() {

        try {
            $DB = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

}

?>

includes/global.inc.php:

<?php

require_once 'classes/DB.class.php';

// Establish Connection to Database.

$db = new DB();
$db->connect();

?>

index.php:

<?php

require_once 'includes/global.inc.php';

$STH = $db->query("SELECT * FROM users");
echo "<pre>";
print_r($STH->fetch());

?>

Solution 1:

You don't have DB property and query() method in your DB class. Add it like this listing:

class DB
    {
    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";
    protected $DB = null;

    // Establish Connection to Database.
    public function connect()
        {
        try
            {
            $this->DB = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name."", $this->db_user, $this->db_pass);
            } 
        catch(PDOException $e)
            {
            echo $e->getMessage();
            }
        }

    public function query()
        {
        return $this->DB->query();
        }
    }

The better way would be to use some ORM library or bare PDO object - it's quite friendly.

Solution 2:

Try this:

class DB extends PDO {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    public function __construct() {
        try {
            parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

}

$db = new DB;
$db->query('SELECT * FROM something');

Also, I added the $this keyword in front of your members, because $db_name and such were not declared in the method scope.

If you do not want the connection to be initiated when the object is created, you could do:

class DB extends PDO {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    public function __construct() {
        // do nothing
    }

    public function connect() {
        try {
            parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

}

$db = new DB;
$db->connect();
$db->query('SELECT * FROM something');

Important note: Normally, when overriding methods in children, you need to specify the same method signature as the parent (or you'll get an E_STRICT error). Fortunately, this doesn't apply to core classes, probably to allow overrides like this.

Solution 3:

The object instantiated as $db does not have the method query. There is probably not a need to wrap the PDO object within another object, but if you are going to do that, you need to make sure all methods are accessible.

Solution 4:

your class DB has no method query! you could do it this way:

<?php

    // DB.class.php

    class DB {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    private $_db;

    // Establish Connection to Database.

    public function connect() {

        try {
            $this->_db = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name, $this->db_user, $this->db_pass);
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

    public function __call($name, array $arguments) {

        if(method_exists($this->_db, $name)){
            try{
                return call_user_func_array(array(&$this->_db, $name), $arguments);
            }
            catch(Exception $e){
                throw new Exception('Database Error: "'.$name.'" does not exists');
            }
         }
     }

}

?>

With the magic function __call() you can pass all functions that PDO supports to your newly created PDO Object.