1

I have a database class that uses PDO. Here's a portion example of it:

class db {
private $host;
private $username;
private $password;
private $con;
    private $pdo;

public function __construct( $database = "dnname" )
{
    $this->host = "localhost";
    $this->username = "username";
    $this->password = "pass";
            $conStr = "host={$this->host};dbname={$database}";
            try {
                $this->pdo = new PDO( "mysql:$conStr", $this->username, $this->password );
                $this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
            }
            catch( PDOException $e ) {
                echo "error ". $e->getMessage();
            }
}

public function fetch_single_row($sql, $data)
{
    if( $data !== null )
        $data = array_values( $data ); // Incase it's an associative array
    $sel = $this->pdo->prepare( $sql );
    $sel->execute( $data );
    $sel->setFetchMode( PDO::FETCH_OBJ );
    $obj = $sel->fetch();
    return $obj;
}

I would like to use this class and its functions (it has more than I've included) inside other classes.

I have tried many many different things, but the only thing that works so far is starting a new instance of db in every new class which I think is bad practice. For instance:

class cms {
   function cms(){
       $this->db = new db();
   }

   function is_admin($id) {
    if($this->db->fetch_single_row("SELECT id FROM user WHERE id = ? LIMIT 1", array($id))){
        return true;
    } else {
        return false;
    }
}

in my index.php, I include these classes and use them:

include("db.class.php");
include("cms.class.php");

$cms = new cms();

if($cms->is_admin($id)){
   //code here
}

What is the correct way to accomplish this?

4
  • 1
    Should your db class's variables be static? It would alleviate most, if not all, performance issues regarding multiple instantiation. In fact, you could just not instantiate a new instance of your db class, but use static functions of your class. Commented Jul 22, 2012 at 4:26
  • __Construct cannot be static, according to php error reporting :) Commented Jul 22, 2012 at 4:32
  • Well, since it's static, you'll only ever need to call any constructing code once. Therefore, explicitly calling a pseudo-constructor after defining the class will do it for you. (But I agree with __construct not being static.) Commented Jul 22, 2012 at 4:34
  • I apologize, I am unsure what you mean. Do you mean changing all the functions in my db class to static, except for the __construct()? Commented Jul 22, 2012 at 4:37

1 Answer 1

3

Take a look into the Singleton Design Pattern, it works great for a DB class

I used to use a class like this for quite a while

   abstract class DB
   {

    protected static $instance;

    protected $db;

    protected static $host = 'host';
    protected static $user = 'user';
    protected static $pass = 'pass';
    protected static $database;

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

        return self::$instance;
    }

    protected function __construct()
    {
        $this->db = new PDO(sprintf('mysql:host=%s;dbname=%s', static::$host, static::$database), static::$user, static::$pass);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    public static function db()
    {
        return static::getInstance()->db;
    }

    public function fetch_single_row($sql, $data)
    {
        if( $data !== null )
            $data = array_values( $data ); // Incase it's an associative array
        $sel = self::db()->prepare( $sql );
        $sel->execute( $data );
        $sel->setFetchMode( PDO::FETCH_OBJ );
        $obj = $sel->fetch();
        return $obj;
    }
}

I would then extend that class for each different database I would need to connect to

class Main extends DB
{
    protected static $database = 'db';
}

You can then use the class like this

$db = Main::getInstance();
$obj = $db->fetch_single_row($sql, $data);
Sign up to request clarification or add additional context in comments.

8 Comments

Whenever you need an instance of the database connection in your application, just call $db = Main::getInstance(); and continue using $db to perform queries
There seems to be a problem with this line: if (!isset(self::$instance)) self::$instance = new static();
I get FATAL ERROR: Call to protected method db::getInstance() from context 'cms' when trying to call $this->db = db::getInstance(); inside my cms class
Which version of PHP are you using? The static keyword is late static binding and is available in php 5.3+. So if you are using an older version, then a quick fix is by not makign it an abstract class
sorry, make the getInstance function public. I have updated my code
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.