Implementation of a Custom Database Class Following Database Class is what I'm using as a wrapper to connect with MySqli in a application, and below the class is how i'm implementing it currently I'm not sure if this is the right way to handle it or how I can further improve.

class Database {
/**
 * @var $conn: type Mysqli
 **/

private $conn = null;
private $stmt = null;

/**
 * @__construct: establishes a new Connection to db
 **/

function __construct() {
    $this-&gt;conn = new mysqli(
        DatabaseHelper::DB_HOST,
        DatabaseHelper::DB_USERNAME,
        DatabaseHelper::DB_PASSWORD,
        DatabaseHelper::DB_NAME 
    );
}

/**
 * @ret: $conn
 **/
public function connect() {
    return $this-&gt;conn ? true : false;
}

public function prepare($query) {
    $this-&gt;stmt = $this-&gt;conn-&gt;prepare($query);
    if ($this-&gt;stmt) {
        return true;
    } else {
        return false;
    }
}

public function set_params($sql_str, ...$params) {
    // bind the sql string
    $bind_args = array();
    $bind_args[] = $sql_str;

    foreach ($params as $param_key =&gt; $param_val) {
        $bind_args[] = &amp;$params[$param_key]; // pass the reference to bind_Args
    }

    if (call_user_func_array(array($this-&gt;stmt, 'bind_param'), $bind_args)) {
        return true;
    } else {
        return false;
    }
}

public function exec_query() {
    $ret = $this-&gt;stmt-&gt;execute();
    $this-&gt;stmt-&gt;close();
    return $ret ? $ret : false;
}

public function exec_query_array() {

    $ret = $this-&gt;stmt-&gt;execute();
    if ($ret) {
        $this-&gt;stmt-&gt;store_result();
        $response = array();
        while($r = $this-&gt;getResultByArray($this-&gt;stmt)) {
            $response[] = $r;
        }
        $this-&gt;stmt-&gt;close();

        return $response;
    } else {
        return false;
    }
}

private function getResultByArray($stmt) {
    if($stmt-&gt;num_rows&gt;0) {
        $result = array();
        $md = $stmt-&gt;result_metadata();
        $params = array();
        while($field = $md-&gt;fetch_field()) {
            $params[] = &amp;$result[$field-&gt;name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params);
        if($stmt-&gt;fetch())
            return $result;
    }
    return null;
}}


and accessing it in this way

 public function findUserByMobile($mobile) {
    $db = new Database();
    $query = "SELECT * FROM users WHERE mobile = ?";
    $sql_str = "s";
    if ($db-&gt;connect()) {
        if ($db-&gt;prepare($query)) {
            if ($db-&gt;set_params($sql_str, $mobile)){
                $ret = $db-&gt;exec_query_array();
                if ($ret) {
                    return $ret;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}


This code is also available here.
Returning Early / Guard Clauses

Returning early is very easy to do and can severely improve your code. 

Looking at findUserByMobile, it is nearly impossible to say which else closes which if on first glance. In this case it doesn't matter that much as all else do the same thing, but it is still not nice to read. 

If you just invert the if and return, the code is a lot nicer:

 public function findUserByMobile($mobile) {
    $db = new Database();
    if (!$db-&gt;connect()) {
        return false;
    }

    $query = "SELECT * FROM users WHERE mobile = ?";    
    if (!$db-&gt;prepare($query)) {
        return false;
    }

    $sql_str = "s";
    if (!$db-&gt;set_params($sql_str, $mobile) ){
        return false;
    }

    $ret = $db-&gt;exec_query_array();
    if (!$ret) {
        return false;
    }
    return $ret;
}


If you don't care what went wrong, you could also combine some of the ifs. In practice, you probably do care though.

Error Handling

Just returning false on error can make debugging quite difficult. Did the query fail because you couldn't connect to the database? Because the query is wrong? Because the parameter is wrong? Because no result could be found? We just don't know. Think about throwing exceptions instead.

Database connections

You really do not want to create a new database connection for each query. Instead, pass the database object to the method and reuse it.

Misc


connect sounds like it would connect something. Instead, it returns something. It is customary to name the method isConnected.
don't shorten variable names. ret is more difficult to read than return or result, metadata is better than md, etc.
always use curly brackets, even for one-line statements.