4
\$\begingroup\$

I'm a beginner PHP developer and it's my first time using MySQLi. I'm not sure if this is a correct implementation of the connection and query because some people defend this method and some others not. I need a solid implementation for heavy database usage.

Connection:

class bbddConnection {


private $_host = 'localhost';
private $_username = 'username';
private $_password = 'password';
private $_db_name = 'DBNAME';
private $_mysqli = NULL;
private static $_instance = NULL;

private function __construct() {
    $this->connection();
}


public static function get_instance() {
    if (!isset(self::$_instance)) {
        //echo "Creating new instance.\n";
        $class_name = __CLASS__;
        self::$_instance = new $class_name;
    }
    return self::$_instance;
}


private function connection() {
    //echo "Creating new connection.\n";
    try {
        //The mysqli object will be created once and only once
        if (!$this->_mysqli instanceof mysqli) {
            $this->_mysqli = new mysqli($this->_host, $this->_username, $this->_password);
        }
        if ($this->_mysqli->connect_errno) {
            throw new Exception('An error occured: ' . $this->_mysqli->connect_error);
        } else {
            $this->select_db();
        }
    } catch (Exception $e) {
        echo $e->getMessage() . "\n";
    }
}

private function select_db() {
    //echo "Selecting database.\n";
    try {
        $this->_mysqli->select_db($this->_db_name) or die('Could not find database');
    } catch (Exception $e) {
        echo $e->getMessage() . "\n";
    }
}

public function query($query) {
    if (!isset($query))
        return;
    //echo "Prevent SQL Injection. \n"
    $query = $this->_mysqli->real_escape_string($query);
    return $this->_mysqli->query($query);
}

public function stmt_init() {
    return $this->_mysqli->stmt_init();
}


public function __destruct() {
    if ($this->_mysqli instanceof mysqli) {
        $this->_mysqli->close();
    }
}

 private function __clone() {
    trigger_error('Clone is not allowed.', E_USER_ERROR);
}

  private function __wakeup() {
    trigger_error('Unserializing is not allowed.', E_USER_ERROR);
}
}

Query:

class gestorUsuarios {

private $db;

public function __construct() {
    $this->db = bbddConnection::get_instance();
}
/**
 * Returns the Name of the user according his ID
 * @param int id
 * @return string Nombre, if an error occurred.
 * returns <b>FALSE</b>
 */
function getUserName($id) 
{

    $stmt = $this->db->stmt_init();
    if ($stmt->prepare("Select Nombre from usuarios where id = ?")) {
        $name = '';
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $stmt->bind_result($name);

        while ($stmt->fetch())
            $nombre = $name;
        $stmt->close();

        return $nombre;
    } else {
          return false;
    }
}
/**
 * Edit the Name of the user according his ID
 * @param String Nombre, int id
 * @return Boolean if an error occurred.
 * returns <b>FALSE</b>, else returns <b>TRUE</b>
 */
function setUserName($nombre, $id) 
{

    $stmt = $this->db->stmt_init();
    if ($stmt->prepare("UPDATE usuarios SET Nombre=? WHERE id =?")) {

        $stmt->bind_param('si', $nombre, $id);
        $stmt->execute();
        $stmt->close();

        return true;
    } else {
        return false;
    }
}
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Similar to this one: Minimalistic mysql db class

To answer your question: NO!

The short answer: Throw away your code, burn it, do whatever you want with it but never use it in a production enviroment. Just don't.

The long answer: Again, don't use this code, ever. You are even violating nearly every SOLID rule

As far as I can see you are trying to write some wrapper around the mysqli object. But the question remains: why? and what problem are you trying to solve?

As far as I can see, you are trying to solve 2 problems with one solution. Oh oh, this is doomed to fail. You want to solve the problem of always having to check wether an instance of mysqli exists or not and you want to not have to worry about connecting and creating a mysqli instance and query-ing/sanitizing the database with a given query. 3 different things.

Then you start designing the solution to that problem. When that is done, you should take a step back and ask the question 'Is my code easy to use?' and 'Is it easy configurable and extendable?' and most important 'is it easy to debug?'.

The answer to those 3 questions is simple: NO!

  • If you want to change a connection parameter you have to change the code of the class itself, bad bad bad.
  • If something goes wrong (an exception) you echo an error message. So what if I first get an instance of your database and it echo's some error message, and then my code sends a header(); . Ooeehh, a nice header allready sent error. Hf debugging that error...
  • ...

But in fact, that isn't your real problem. The real problem you have is that you are writing code without designing it.

If your problem is that you want only one instance to exist you should only create one instance instead of relying on a get_instance() function or Singleton pattern. If a class needs a database connection, pass it in in the __construct(). More on this topic:

To sum up, sometimes the problems we are solving tend to be meta-problems. The solution we make is actually a fix. A good article on this: http://thedailywtf.com/Articles/The_Complicator_0x27_s_Gloves.aspx

On a complete diffrent note, instead of using mysqli. use PDO. This is a realy nice OO way of using a database. more on pdo:

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for your reply. Before I change the code, I would like to discuss a certain topic:- PDO: the connections to databases with PDO may be more 'independent' (for compatibility) and even facilitate interactions, but DO NOT offer the same performance as Mysqli connection. Doing that is not as optimized as possible, so I decided to use Mysqli instead of PDO. But I only read a lot of pages talking about migrating from mysqli PDO, so I would like to be sure that the benefits are sufficient to dispense with the performancepd: sorry for my English -.-'' \$\endgroup\$
    – RmG152
    Commented Aug 21, 2013 at 16:03
  • 1
    \$\begingroup\$ @RmG152 PDO isn't slower then mysqli: jnrbsn.com/2010/06/mysqli-vs-pdo-benchmarks If your application is slower with PDO, it's they way you are using PDO. Here a good comparison between pdo and mysqli: net.tutsplus.com/tutorials/php/… \$\endgroup\$
    – Pinoniq
    Commented Aug 22, 2013 at 7:43
  • \$\begingroup\$ Agree completely with @Pinoniq on performance. PDO is implemented as an extension and is thus going to be faster than any PHP connection object that you could write (unless maybe you made your own extension). Of course it's doubtful that you would actually notice any speed difference. \$\endgroup\$
    – Cerad
    Commented Aug 22, 2013 at 16:44

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.