Passing DB access class with REQUIRE or dependency injection?

186 views Asked by At

Similar questions have been asked but I believe they do not cover my case.

I experimented with a few ways to pass db class to other classes for access and found that the below works well. My question is: is there anything wrong with that approach and whether Dependency Injection will be a better solution?

class Database{

    private $db_host = "localhost";
    private $db_user = "root";
    private $db_password = "";
    private $db_name = "dbName";    

    private $pdo;
    public  $instance;


    function __construct() {
        try{
            //create a PDO connection and assign it to some handler
            $this->pdo = new PDO('mysql:host='. $this->db_host.';dbname='. $this->db_name, $this->db_user,  $this->db_password);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
           // echo "connected";
        } catch (PDOException $e) {
            exit("Error connecting to database". $e->getMessage());
        }
    }    


    public function getPDO(){
        return $this->pdo;
    }



}

class OtherClass{
    require_once 'Database.php';
    private $db_instance;
    private $dbh;

    function __construct() {
       $this->db_instance = new Database();
       $this->dbh = $this->db_instance->getPDO();
    } 


}
1

There are 1 answers

0
Nelson Owalo On

How about a simple class from which you can create and destroy a connection to the database if its not needed. Lets refractor your code abit.

First create a classname that can be identified easily, something like

class pdo_mysql{

Its a pdo class, but based on mysql, next declare some variables, (The explanation in the comments)

/*
* Description   -   The name of the database
*/
private $dbname;

/*
* Description   -   The database username
*/
private $dbuser;

/*
* Description   -   The database password
*/
private $dbpass;

/*
* Description   -   The database Host
*/
private $dbhost;

/*
* Description   -   The database driver 
* @Parameters   -   null
* To do         -  
* Notes: 
*/
private $dbdriver;
/*
* Description   -   Stores the connection to the database
*/
private $con;

Then lets define the constructor for our class:

/*
* Description   -   This is the default method that is called when this class is instantiated.
* @Parameters   -   dbhost|dbdriver|dbname|dbusername|dbpassword
*/
function __construct($dbhost, $dbdriver, $dbname, $dbuser, $dbpass){         
    $this->dbhost = $dbhost;
    $this->dbdriver = $dbdriver;
    $this->dbname = $dbname;
    $this->dbuser = $dbuser;
    $this->dbpass = $dbpass;
}

Note that when the class is instantiated, most class variables are set. Then our connection function:

/*
* Description   -   Creates a connection to the database
* Notes:        -   Returns true on success || string with an error msg on failure
*/
private function _connect(){
    try {
            $this->con = new PDO(''.$this->dbdriver.':host='.$this->dbhost.';dbname='.$this->dbname.'', $this->dbuser, $this->dbpass);
            $this->con->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
            $this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            return true;
        }   catch (PDOException $e){    
            return $e->getMessage();
        }               
}

And finally a function to disconnect our connectio to the database:

/*
* Description   -   Disconnects database connection
*/
private function _disconnect(){$this->con = null;return true;}

And a finally a function to query the database:

/*
* Description   -   Retrieves information from the database
*/
function _loadResult($data){}

This class will use data that is pre populated, so lets create for it a function to initialize it: (this should be in a different file/class)

/*
* Description   -   Get the config options from a file and initiate the database object
* Notes:        -   Returns a new object of the database connection class on success | false on fail
                    the config file must contain the following values dbhost|dbengine|dbname|dbusername|dbpassword
*/
static public function getDbo(){
    if(!is_readable(/*path to your config file*/)){// lets check that the config file exists and is readable
        return 'ERROR - The config file is missing or its unreadable!';
    }

    $config = parse_ini_file(/*path to your config file*/);     
    if($config === false){//parse the config file and return an error incase the purse fails 
        return 'ERROR - Could not parse the config file!';
    }

//the following values are populated by the ones parsed from the config file
    $dbhost = $config['dbhost'];
    $dbclassprefix = $config['dbclassprefix'];
    $dbdriver = $config['dbdriver'];
    $dbname = $config['dbname'];
    $dbuser = $config['dbuser'];
    $dbpass = $config['dbpass'];        

    static $dbobject = null;//create the database object if all went well
    if(null === $dbobject){$dbclass = $dbclassprefix.$dbdriver;$dbobject = new $dbclass($dbhost, $dbdriver, $dbname, $dbuser, $dbpass);}
    return $dbobject;//return the database object
}

A case usage of the above code:

$db = self::getDbo();//create the database object

    if(is_string($db)){//if the return value is a string, then thats an error
        //return an error
    }

    $res = $db->_loadResult($data);//call a function from the database class

This is just a shaddy example from my head to give you some rough ideas, but its fully guaranteed to work if coded correctly, with the above classes and functions, you can change the engine to either PDO_mysqli or another another by changing the value in your config file. Hope you get the idea