* @copyright creative commons attribution-shareAlike 3.0 unported
* @license http://creativecommons.org/licenses/by-sa/3.0/
* @version 2.05.02
*/
namespace qoob\core\db;
class mysqli {
/**
* error constants
*/
const
E_Server = 'Failed to connect: %s',
E_Database = 'Failed to select database: %s';
protected
/**
* @var object $db the database reference
*/
$db = null,
/**
* @var string $sql the sql query
*/
$sql = null;
private
/**
* @var string $dbhost the database hostname
*/
$dbhost,
/**
* @var string $dbuser the database username
*/
$dbuser,
/**
* @var string $dbpass the database password
*/
$dbpass,
/**
* @var string $dbname the database name
*/
$dbname,
/**
* @var bool $asciiOnly true will allow only ascii characters, false will allow all printable characters
*/
$asciiOnly = true,
/**
* @var bool $keepAlive true will not close the mysqli connection on class destruction
*/
$keepAlive = false,
/**
* @var int $count mysqli_num_rows result
*/
$count = 0;
/**
* initializer
* set the database connection variables and optionally the asciiOnly variable
*
* @param string $db_host
* @param string $db_user
* @param string $db_pass
* @param string $db_name
* @param boolean $asciiOnly default = true
*/
public function init($db_host, $db_user, $db_pass, $db_name, $asciiOnly=true, $keepAlive=false) {
$this->dbhost = $db_host;
$this->dbuser = $db_user;
$this->dbpass = $db_pass;
$this->dbname = $db_name;
$this->asciiOnly = $asciiOnly;
$this->keepAlive = $keepAlive;
}
/**
* is ascii
* set the asciiOnly variable to true and allow only ascii characters in sql queries, false will allow all printable characters.
*
* @param boolean $asciiOnly default = true
*/
public function isAscii($asciiOnly) {
$this->asciiOnly = $asciiOnly;
}
/**
* connect
* connect to a mysqli server and selects the appropriate database. throw a dbException on failure.
*/
public function connect() {
if(($db = @\mysqli_connect($this->dbhost, $this->dbuser, $this->dbpass)) === false) {
throw new dbException(sprintf(self::E_Server, $this->dbuser.'@'.$this->dbhost));
}
if((@\mysqli_select_db($db, $this->dbname)) === false) {
throw new dbException(sprintf(self::E_Database, $this->dbname));
}
$this->db = $db;
}
/**
* reconnect function
* connect to a new database server and optionally disconnect from the old one.
*
* @param string $db_host
* @param string $db_user
* @param string $db_pass
* @param string $db_name
* @param boolean $closeOld
*/
public function reconnect($db_host, $db_user, $db_pass, $db_name, $closeOld=true) {
if($closeOld){
mysqli_close($this->db);
}
$this->init($db_host, $db_user, $db_pass, $db_name);
$this->connect();
}
/**
* sanitize
* mitigate attack vectors by removing offending slashes, removing non printable characters, and filtering it against the mysqli server's own escape function.
*
* @param string $string
* @return string
*/
public function sanitize($string) {
if(get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
$filtered = trim($this->asciiOnly ? preg_replace('/[^\x0A\x0D\x20-\x7E]/', '', $string) : preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string));
return mysqli_real_escape_string($this->db, str_replace('$', '$\\', $filtered));
}
/**
* SQL query function
* executes a mysqli query. make sure all insert, and update statements have the results flag set to false.
*
* @param string $sql
* @param array $args
* @param boolean $results
* @param boolean $count
* @return object|boolean
*/
public function query($sql, $args = array(), $results = true, $count = false) {
$find = array();
$replace = array();
foreach ($args as $key => $value) {
$find[] = '/:'.$key.'/';
$replace[] = $this->sanitize($value);
}
$this->sql = preg_replace($find, $replace, $sql);
$query = new mysqliQuery($this->sql, $this->db);
if(substr(trim((strtolower($this->sql))), 0, 6) === 'select') {
$this->count = $count ? $query->num_rows() : 0;
} else {
$this->count = $count ? $query->affected_rows() : 0;
}
if($results) {
return $query->result();
} else {
return true;
}
}
/**
* get insertID
* get the last inserted record's id
*
* @return int|string
*/
public function insertID() {
return mysqli_insert_id($this->db);
}
/**
* get num_rows
* returns the numbers of rows from a query
*
* @return int|string
*/
public function num_rows() {
return $this->count;
}
/**
* destructor
* if keepAlive is false close the connection when finished
*/
public function __destruct() {
if(!$this->keepAlive) {
if (isset($this->db) && is_resource($this->db)) {
@mysqli_close($this->db);
}
}
}
}
/**
* mysqli query
* class for executing queries and handling mysqli results.
*/
class mysqliQuery {
protected $result;
/**
* constructor
* gets the results of the mysqli query or throws a dbException error
*
* @param string $query
* @param object $link mysqli_connection
*/
public function __construct($query, $link) {
if(($this->result = @mysqli_query($link, $query)) === false) {
throw new dbException($query, 500);
}
}
/**
* get result
* returns the results of the mysqli query
*
* @return array
*/
public function result() {
$result = array();
while (($row = @mysqli_fetch_assoc($this->result)) != false) {
$result[] = $row;
}
return $result;
}
/**
* number of rows
* returns the number of rows in a given result
*
* @return int
*/
public function num_rows() {
return @mysqli_num_rows($this->result);
}
/**
* number of affected rows
* returns the number of rows affected by the previous sql query
*
* @return int
*/
public function affected_rows() {
return @mysqli_affected_rows();
}
/**
* destructor
* call's free result only if one has been created
*/
public function __destruct() {
if(is_array($this->result)) {
@mysqli_free_result($this->result);
}
}
}
/**
* database exception
*
*/
class dbException extends \Exception {
/**
* constructor
* sets the error code and message
*
* @param string $message
* @param int $code 500
*/
public function __construct($message, $code = 500) {
$this->code = $code;
$this->message = mysqli_error().PHP_EOL."
".PHP_EOL.$message;
}
}
?>