March 4, 2012

Database class design

Question by JamWaffles

I’m creating a web app with various classes for things like the user, Smarty template control, etc.

I already have a database class which is all well and good, but I’m concerned about the performance of it.

Currently, in another class, I’m doing $this->db = new DB() to create a local database instance, however the database class’s __construct() function creates a new connection to the MySQL server every time I make a new DB() instance, which is obviously less than sensible. This means that each instance of all my different classes that uses the database class makes a connection to the server. I don’t have a vast amount of classes, but I only want one per page load.

This is a stripped down sample of what I have at the moment:

// Database class used by multiple other classes
class DB {
    private $dbh;

    function __construct() {
        $this->dbh = // PDO connection here
    }

    public function query($str) {
        // Do a query
    }
}

// Example class User
class User {
    private $db;    // Stores local instance of DB class.

    function __construct() {
        $this->db = new DB();    // Makes a new connection in DB::__construct()
    }

    public function login() {
        $this->db->query('SELECT * FROM users');
    }
}

I’m looking for the “best” or most common practice of doing this. I don’t want to make 10-ish separate connections for each page load.

I want to know what the best way of using and managing a DB class in my application. My four thoughts are these:

  1. Would using a persistent connection to the MySQL server solve this multiple connection issue for me?
  2. Should I use a static factory class and return a DB instance instead of using new DB()?
  3. Is the proper solution to use an entirely static class and just do DB::query() (for example) every time I reference it?
  4. I often use multiple classes in another (so we might have class Folders which requires classes User, DB and Smarty). Is it general practice to extend each class somehow?

Answer by Brent Baisley

If you make the variable holding the connection static, then you can check if you already established a connection. Static variables are the same across all instances of the class, so you can create 100 instances that all use the same connection. You just need to reference it statically: self::$dbh instead of $this->dbh.

class DB {
    private static $dbh = null;

    function __construct() {
        if ( is_null(self::$dbh) ) {
            self::$dbh = // PDO connection here
        }
    }
 }

Answer by Starx

I would suggest you to check the $this -> db at first and then only create it.

function __construct() {
        if(!isset($this -> db) || !is_a("DB", $this -> db)) {
         $this->db = new DB();    // Makes a new connection in DB::__construct()
    }
}

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!