tags:

views:

653

answers:

5

I want to be able to make classes which extend the MySQLi class to perform all its SQL queries.

$mysql = new mysqli('localhost', 'root', 'password', 'database') or die('error connecting to the database');

I dont know how to do this without globalising the $mysql object to use in my other methods or classes.

class Blog {

public function comment() {
 global $mysql;

 //rest here
}

}

Any help would be appreciated.

Thanks.

A: 

My suggestion is to create a Singleton DataAccess class, instantiate that class in a global config file and call it in your Blog class like $query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id).

Look into the Singleton pattern, it's a pretty easy to understand designpattern. Perfect for this situation.

Your DataAccess class can have several methods like query, fetchAssoc, numRows, checkUniqueValue, transactionStart, transactionCommit, transactionRollback etc etc. Those function could also be setup as an Interface which gets implemented by the DataAccess class. That way you can easily extend your DataAccess class for multiple database management systems.

The above pretty much describes my DataAccess model.

Ben Fransen
If i use singletons, would it create a new connection to the database everytime its called?
bennn
No, thats the idea of Singleton. You create one instance and you keep using that instance by calling it static. So you have 1 db connection for all classes / controllers / views etc.
Ben Fransen
Ben thanks for your help, this worked perfectly!
bennn
You're welcome!
Ben Fransen
A: 

You can use PHP's extends keyword just for any other class:

class Blog extends mysqli {

    public function __construct($host, $user, $password, $database) {
     parent::__construct($host, $user, $password, $database);
    }

    public function someOtherMethod() {
    }
}

$blog = new Blog('localhost', 'root', 'password', 'database') or die('Cannot connect!');

or better use object aggregation instead of inheritance:

class Blog {

    private $db;

    public function __construct($host, $user, $password, $database) {
     $this->db = new mysqli($host, $user, $password, $database);
    }

    public function someOtherMethod() {
     return $this->db->query("SELECT * FROM blah_balh");
    }
}
eyazici
Thats a whacked solution beause in NO way Blog is an extension of the mysqli class. It simply uses it, not extends it with new functionallity provided for data-access.
Ben Fransen
It is clear Blog's itself cannot be a subclass of database object, I used to answer question, not to judge application design.
eyazici
A: 

My standard method is to make a singleton class that acts as the database accessor, and a base class that everything requiring such access inherits from.

So:

class Base {

  protected $db;

  function __construct(){
    $this->db= MyDBSingleton::get_link();
    //any other "global" vars you might want 
  }

}


class myClass extends Base {

  function __construct($var) {
     parent::__construct();// runs Base constructor
     $this->init($var);
  }

  function init($id) {
    $id=(int) $id;
    $this->db->query("SELECT * FROM mytable WHERE id=$id");
    //etc.
  }
}
dnagirl
A: 

Have a look at PDO, which throw exceptions for you to catch if a query fails. It's widely used and tested so you shouldn't have a problem finding existing solutions whilst using it.

To inject it into your blog class:

class Blog {

    private $_db;

    public function __construct(PDO $db) {
        $this->_db = $db
    }

    public function comment() {
        return $this->_db->query(/*something*/);
    }

}
chelmertz
A: 

I was working on something similar. I'm happy about this singleton class that encapsulates the database login.

<?php
class db extends mysqli
{
    protected static $instance;
    protected static $options = array();

    private function __construct() {
        $o = self::$options;

        // turn of error reporting
        mysqli_report(MYSQLI_REPORT_OFF);

        // connect to database
        @parent::__construct(isset($o['host'])   ? $o['host']   : 'localhost',
                             isset($o['user'])   ? $o['user']   : 'root',
                             isset($o['pass'])   ? $o['pass']   : '',
                             isset($o['dbname']) ? $o['dbname'] : 'world',
                             isset($o['port'])   ? $o['port']   : 3306,
                             isset($o['sock'])   ? $o['sock']   : false );

        // check if a connection established
        if( mysqli_connect_errno() ) {
            throw new exception(mysqli_connect_error(), mysqli_connect_errno()); 
        }
    }

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

    public static function setOptions( array $opt ) {
        self::$options = array_merge(self::$options, $opt);
    }

    public function query($query) {
        if( !$this->real_query($query) ) {
            throw new exception( $this->error, $this->errno );
        }

        $result = new mysqli_result($this);
        return $result;
    }

    public function prepare($query) {
        $stmt = new mysqli_stmt($this, $query);
        return $stmt;
    }    
}

To use you can have something like this:

<?php
require "db.class.php";

$sql = db::getInstance();

$result = $sql->query("select * from city");

/* Fetch the results of the query */ 
while( $row = $result->fetch_assoc() ){ 
    printf("%s (%s)\n", $row['Name'], $row['Population']); 
} 
?>
Yada