'localhost', 'user' => 'root', 'pass' => '', 'db' => 'test', 'port' => NULL, 'socket' => NULL, 'pconnect' => FALSE, 'charset' => 'utf8', 'errmode' => 'error', //or exception 'exception' => 'Exception', //Exception class name ); const RESULT_ASSOC = MYSQLI_ASSOC; const RESULT_NUM = MYSQLI_NUM; function __construct($opt = array()) { $opt = array_merge($this->defaults,$opt); $this->emode = $opt['errmode']; $this->exname = $opt['exception']; if ($opt['pconnect']) { $opt['host'] = "p:".$opt['host']; } @$this->conn = mysqli_connect($opt['host'], $opt['user'], $opt['pass'], $opt['db'], $opt['port'], $opt['socket']); if ( !$this->conn ) { $this->error(mysqli_connect_errno()." ".mysqli_connect_error()); } mysqli_set_charset($this->conn, $opt['charset']) or $this->error(mysqli_error($this->conn)); unset($opt); // I am paranoid } public function query() { return $this->rawQuery($this->prepareQuery(func_get_args())); } public function fetch($result,$mode=self::RESULT_ASSOC) { return mysqli_fetch_array($result, $mode); } public function affected_rows() { return mysqli_affected_rows ($this->conn); } public function insert_id() { return mysqli_insert_id($this->conn); } public function num_rows($result) { return mysqli_num_rows($result); } public function free($result) { mysqli_free_result($result); } public function getOne() { $query = $this->prepareQuery(func_get_args()); if ($res = $this->rawQuery($query)) { $row = $this->fetch($res); if (is_array($row)) { return reset($row); } $this->free($res); } return FALSE; } public function getRow() { $query = $this->prepareQuery(func_get_args()); if ($res = $this->rawQuery($query)) { $ret = $this->fetch($res); $this->free($res); return $ret; } return FALSE; } public function getCol() { $ret = array(); $query = $this->prepareQuery(func_get_args()); if ( $res = $this->rawQuery($query) ) { while($row = $this->fetch($res)) { $ret[] = reset($row); } $this->free($res); } return $ret; } public function getAll() { $ret = array(); $query = $this->prepareQuery(func_get_args()); if ( $res = $this->rawQuery($query) ) { while($row = $this->fetch($res)) { $ret[] = $row; } $this->free($res); } return $ret; } public function getInd() { $args = func_get_args(); $index = array_shift($args); $query = $this->prepareQuery($args); $ret = array(); if ( $res = $this->rawQuery($query) ) { while($row = $this->fetch($res)) { $ret[$row[$index]] = $row; } $this->free($res); } return $ret; } public function getIndCol() { $args = func_get_args(); $index = array_shift($args); $query = $this->prepareQuery($args); $ret = array(); if ( $res = $this->rawQuery($query) ) { while($row = $res->fetch($res)) { $key = $row[$index]; unset($row[$index]); $ret[$key] = reset($row); } $this->free($res); } return $ret; } public function parse() { return $this->prepareQuery(func_get_args()); } public function whiteList($input,$allowed,$strict=FALSE) { $found = array_search($input); if ($strict && ($found === FALSE)) { return FALSE; } else { return $allowed[$found]; } } public function filterArray($input,$allowed) { foreach(array_keys($input) as $key ) { if ( !in_array($key,$allowed) ) { unset($input[$key]); } } return $input; } private function rawQuery($query) { $this->lastquery = $query; $res = mysqli_query($this->conn, $query) or $this->error(mysqli_error($this->conn).". Full query: [$query]"); return $res; } private function prepareQuery($args) { $raw = $query = array_shift($args); preg_match_all('~(\?[a-z?])~',$query,$m,PREG_OFFSET_CAPTURE); $pholders = $m[1]; $count = 0; foreach ($pholders as $i => $p) { if ($p[0] != '??') { $count++; } } if ( $count != count($args) ) { $this->error("Number of args (".count($args).") doesn't match number of placeholders ($count) in [$raw]"); } $shift = 0; $qmarks = 0; foreach ($pholders as $i => $p) { $pholder = $p[0]; $offset = $p[1] + $shift; if ($pholder != '??') { $value = $args[$i-$qmarks]; } switch ($pholder) { case '?n': $value = $this->escapeIdent($value); break; case '?s': $value = $this->escapeString($value); break; case '?i': $value = $this->escapeInt($value); break; case '?a': $value = $this->createIN($value); break; case '?u': $value = $this->createSET($value); break; case '??': $value = '?'; $qmarks++; break; case '?p': break; default: $this->error("Unknown placeholder type ($pholder) in [$raw]"); } $query = substr_replace($query,$value,$offset,2); $shift+= strlen($value) - strlen($pholder); } return $query; } private function escapeInt($value) { if (is_float($value)) { return number_format($value, 0, '.', ''); // may lose precision on big numbers } elseif(is_numeric($value)) { return (string)$value; } else { $this->error("Invalid value for ?i (int) placeholder: [$value](".gettype($value).")"); } } private function escapeString($value) { return "'".mysqli_real_escape_string($this->conn,$value)."'"; } private function escapeIdent($value) { if ($value) { return "`".str_replace("`","``",$value)."`"; } else { $this->error("Empty value for ?n (identifier) placeholder."); } } private function createIN($data) { if (!is_array($data)) { $this->error("Value for ?a (IN) placeholder should be array."); return; } if (!$data) { return 'NULL'; } $query = $comma = ''; foreach ($data as $key => $value) { $query .= $comma.$this->escapeString($value); $comma = ","; } return $query; } private function createSET($data) { if (!is_array($data)) { $this->error("Value for ?u (SET) placeholder should be an array. ".gettype($data)." passed instead."); return; } if (!$data) { $this->error("Empty array for ?u (SET) placeholder."); return; } $query = $comma = ''; foreach ($data as $key => $value) { $query .= $comma.$this->escapeIdent($key).'='.$this->escapeString($value); $comma = ","; } return $query; } private function error($err) { $err = __CLASS__.": ".$err; if ( $this->emode == 'error' ) { $err .= ". Error initiated in ".$this->caller().", thrown"; trigger_error($err,E_USER_ERROR); } else { throw new $this->exname($err); } } private function caller() { $trace = debug_backtrace(); $caller = ''; foreach ($trace as $t) { if ( isset($t['class']) && $t['class'] == __CLASS__ ) { $caller = $t['file']." on line ".$t['line']; } else { break; } } return $caller; } }