Gary Gary - 3 months ago 28
PHP Question

Using MySQLi methods via child class

I'm trying to make use of the MySQLi class, but don't want to have to write out the connection details each time. What I've been trying to do is make an extended class of

mysqli
, called
database
that will return a connection handler and eventually fail gracefully if no connection can be made (I've not done that yet).

But, the problem I've ran into is (and I apologise now if this is incredibly easy) I'm unable to use accesss the
mysqli
methods to prepare, bind and execute statements in my other classes after instantiating the child class
database
and passing it to the method that needs it.

Am I going down the right route? As MySQLi can be implemented OOP, I thought writing a whole new class just to use it when I can use the required methods in each class was sort of defeating the point of it?

Below is my
database
class that extends
mysqli
.

class database extends mysqli{

//set connection variables
private $host = "localhost";
private $username = "username";
private $password = "password";
private $db_name = "db_name"; //database name

public function connect(){
$mysqli = new mysqli($this->host, $this->username, $this->password, $this->db_name);

if ($mysqli->connect_errno){//check if any connection error was encountered
return false;
} else {
return $mysqli;
}
}
}


And this is my registration class that will potentially be preparing statements, executing queries etc.

class registration{

private $email;
private $sec_email;
private $password;
private $sec_pass;
private $code;

function __construct($code, $email, $sec_email, $password, $sec_pass){
//Sets all the vars above
}

public function check_vars(){//Check variables are set and valid.
$mysqli = new database;
if($mysqli){
$code_check = $this->check_code($this->code, $mysqli);
if($code_check == true){
//Code checks out
}
}
}

private function check_code($code, $mysqli){
if($stmt = $mysqli->prepare("SELECT `code` FROM `code_list` WHERE `code` = ? LIMIT 1")){
//return true
}
}
}


Thanks in advance and I apologise if there is an easy answer that I've overlooked.

UPDATE


Since reading the answer left by @Your Common Sense, I've done the following:

index.php

require_once('config.php');
$mysqli = new mysqli($db['host'], $db['user'], $db['pass'], $db['dbname']);
$display = new dispaly($mysqli);
//Display methods...


config.php

$db = array('host' => 'host', 'user' => 'user', 'pass' => 'pass', 'dbname' => 'dbname')
require_once('lib/other.classes.php');
//More classes


Mainly wanted to add that since this answer was supplied, I've started to use Dependency Injection for a lot of other objects too, instead of instantiating new ones everytime I needed them.

Thank @Your Common Sense, and @Bill Karwin!

Answer

Am I going down the right route?

Definitely no

First, you don't need no dedicated database class to gracefully fail. It have to be done centralized in the application-wide error handler for ALL the errors at once, not for the every API separately.

Second, your idea of creating a new database class instance in every class is just terrible.

So, here is the right direction:

  1. Create just plain and raw mysqli class instance. Once.
  2. Pass it as argument in other classes constructors.

So here goes your application class

class registration()
{
    private $db;
    public $email;
    public $sec_email;
    public $password;
    public $sec_pass;
    public $code;

    function __construct($mysqli)
    {
        $this->db = $mysqli;
    }

    public function init($code, $email, $sec_email, $password, $sec_pass)
    {
        $code_check = $this->check_code($this->code);
    }

    private function check_code($code)
    {
        $sql  = "SELECT `code` FROM `code_list` WHERE `code` = ? LIMIT 1";
        $stmt = $this->db->prepare($sql);
    }
}

In the future, then you make yourself familiar with mysqli and its drawbacks, consider writing (or adopting) mysqli wrapper class. A sensible one.