views:

456

answers:

2

I have a few classes that perform some MySQL queries and prepared statements. However, I am lost in how to incorporate my PDO object within those classes. For example, I want to do something like this:

<?php

$dbh = new PDO(...);

class Foo extends PDO {
    public $dbh;

    public function bar() {
        $this->dbh->prepare('SELECT * FROM table');
        $this->dbh->execute();

    }
}


?>

Unfortunately, it doesn't work. Can anyone suggest an elegant way to do this? Thanks for your time. Sorry I'm new to this, please leave any comments if you are unclear about anything and I'll do my best to respond!

+1  A: 

$dbh isn't within the scope of Foo, do this instead:

class Foo /*extends PDO*/
{
    public $dbh;

    public function __construct()
    {
        $dbh = new PDO(/*...*/);
    }

    public function bar()
    {
        $this->dbh->prepare('SELECT * FROM table');
        return $this->dbh->execute();
    }
}

Also, Foo doesn't need to extend PDO.

Alix Axel
Would that slow the database/script down since I am making a new connection each time I create an object?
Axsuul
Why would you need to instantiate the object more than once?
Alix Axel
I meant to say I have 14 *different* objects in a script, and they all need database connections, so therefore wouldn't I be making 14 database connections?
Axsuul
No, `Foo` will only be instantiated once, hence only one PDO connection.
Alix Axel
But what if I have other objects, like `Bar`, `Moo`, `Cow`, `Barn` and they also need to make database queries, so wouldn't that be +4 more db connections? Thanks for sticking with me
Axsuul
Yes, in those casse we normally use a something called `singleton`. Read about it on Wikipedia and if you still have question ask another question here.
Alix Axel
+3  A: 

You can instanciate your connection to the database in a class that implement the singleton pattern. The connection will be done once and this class will be easily accessible by all of your other objects / scripts.

i use a class called "Core" in the following exemple;

class Core
{
    public $dbh;   // handle of the db connexion
    private static $dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    private static $user = 'myuser';
    private static $pass = 'mypassword';


    public function __construct () {
      $this->dbh = new PDO(self::$dsn,self::$user,self::$pass);
    }

    public static function getInstance(){
        if(!isset(self::$instance)){
            $object= __CLASS__;
            self::$instance=new $object;
        }
        return self::$instance;
    }

    // others global functions
}

in all your scripts / objects you just have to get the instance of Core and then query the DB

$sql = "select login, email from users where id = :id";

try {
    $core = Core::getInstance();
    $stmt = $core->dbh->prepare($sql);
    $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);

    if ($stmt->execute()) {
        $o = $stmt->fetch(PDO::FETCH_OBJ);
        // blablabla....

If you need more informations about singleton look at the php doc http://php.net/manual/en/language.oop5.patterns.php

Guillaume Boschini
Wow this is awesome and works perfectly. Thanks for the suggestion, it's nice and elegant :) This will definitely be one of the coding practices that will stick with me through different projects!
Axsuul
you're welcome; i use the Core class to store other usefull things that need to be accessible in many of my scripts, like the object that contains the logged user...it's very convenient
Guillaume Boschini
I think 'private static $instance;' needs to be declared as a property, otherwise you will get Access to undeclared static property: Core::$instance.
Ben