This database class is beginner-friendly and easy to implement, with the native MySQLi methods you need to write 3-7 lines of code to retrieve data from a database, with this class you can do it with just 1-2 lines of code, and is much easier to understand.
Create a new file and name it db.php
and add:
<?php
class Database {
protected $connection;
protected $query;
protected $show_errors = TRUE;
protected $query_closed = TRUE;
public $query_count = 0;
public function __construct($dbhost = 'localhost', $dbuser = 'root', $dbpass = '', $dbname = '', $charset = 'utf8') {
$this->connection = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($this->connection->connect_error) {
$this->error('Failed to connect to MySQL - ' . $this->connection->connect_error);
}
$this->connection->set_charset($charset);
}
public function query($query) {
if (!$this->query_closed) {
$this->query->close();
}
if ($this->query = $this->connection->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_slice($x, 1);
$types = '';
$args_ref = array();
foreach ($args as $k => &$arg) {
if (is_array($args[$k])) {
foreach ($args[$k] as $j => &$a) {
$types .= $this->_gettype($args[$k][$j]);
$args_ref[] = &$a;
}
} else {
$types .= $this->_gettype($args[$k]);
$args_ref[] = &$arg;
}
}
array_unshift($args_ref, $types);
call_user_func_array(array($this->query, 'bind_param'), $args_ref);
}
$this->query->execute();
if ($this->query->errno) {
$this->error('Unable to process MySQL query (check your params) - ' . $this->query->error);
}
$this->query_closed = FALSE;
$this->query_count++;
} else {
$this->error('Unable to prepare MySQL statement (check your syntax) - ' . $this->connection->error);
}
return $this;
}
public function fetchAll($callback = null) {
$params = array();
$row = array();
$meta = $this->query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($this->query, 'bind_result'), $params);
$result = array();
while ($this->query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
if ($callback != null && is_callable($callback)) {
$value = call_user_func($callback, $r);
if ($value == 'break') break;
} else {
$result[] = $r;
}
}
$this->query->close();
$this->query_closed = TRUE;
return $result;
}
public function fetchArray() {
$params = array();
$row = array();
$meta = $this->query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($this->query, 'bind_result'), $params);
$result = array();
while ($this->query->fetch()) {
foreach ($row as $key => $val) {
$result[$key] = $val;
}
}
$this->query->close();
$this->query_closed = TRUE;
return $result;
}
public function close() {
return $this->connection->close();
}
public function numRows() {
$this->query->store_result();
return $this->query->num_rows;
}
public function affectedRows() {
return $this->query->affected_rows;
}
public function lastInsertID() {
return $this->connection->insert_id;
}
public function error($error) {
if ($this->show_errors) {
exit($error);
}
}
private function _gettype($var) {
if (is_string($var)) return 's';
if (is_float($var)) return 'd';
if (is_int($var)) return 'i';
return 'b';
}
}
Connect to MySQL database:
include 'Database.php';
$dbhost = 'localhost';
$dbuser = 'username';
$dbpass = 'password';
$dbname = 'database_name';
$database = new Database($dbhost, $dbuser, $dbpass, $dbname);
$account = $db->query('SELECT * FROM accounts WHERE username = ? AND password = ?', 'test', 'test')->fetchArray();
echo $account['name'];
Or you could do:
$account = $db->query('SELECT * FROM accounts WHERE username = ? AND password = ?', array('test', 'test'))->fetchArray();
echo $account['name'];
$accounts = $db->query('SELECT * FROM accounts')->fetchAll();
foreach ($accounts as $account) {
echo $account['name'] . '<br>';
}
You can specify a callback if you do not want the results being stored in an array (useful for large amounts of data):
$db->query('SELECT * FROM accounts')->fetchAll(function($account) {
echo $account['name'];
});
If you need to break the loop you can add:
return 'break';
$accounts = $db->query('SELECT * FROM accounts');
echo $accounts->numRows();
$insert = $db->query('INSERT INTO accounts (username,password,email,name) VALUES (?,?,?,?)', 'test', 'test', '[email protected]', 'Test');
echo $insert->affectedRows();
echo $db->query_count;
echo $db->lastInsertID();
$db->close();
The database class uses the MySQLi extension, this is built into PHP version >= 5.0.0. If you're using PHP version 5.0.0 to 5.3.0 you'll need install: mysqlnd.
No need to prepare statements using this class, it'll do that for you automatically (write less, do more), your queries will be secure, just remember to make sure you escape your output using htmlspecialchars
, or your preferred escaping method.
You're free to use this database class in your projects.
Released under the MIT
License.
Author: Marko Radulovic
Find me on: LinkedIn
Email: [email protected]
Thanks David Adams on help.