|
|
@ -1,4 +1,5 @@ |
|
|
|
<?php |
|
|
|
<?php |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @author col.shrapnel@gmail.com |
|
|
|
* @author col.shrapnel@gmail.com |
|
|
|
* @link http://phpfaq.ru/safemysql |
|
|
|
* @link http://phpfaq.ru/safemysql |
|
|
@ -65,15 +66,63 @@ |
|
|
|
* $data = $db->getAll("SELECT * FROM table WHERE ?p", $bar, $sqlpart); |
|
|
|
* $data = $db->getAll("SELECT * FROM table WHERE ?p", $bar, $sqlpart); |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
class SafeMySQL { |
|
|
|
|
|
|
|
#########################ТВИКИ ОТ ЗУМА###################### |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* удаляет строки из таблицы, принимает массив вида |
|
|
|
|
|
|
|
* 0=>имя таблицы |
|
|
|
|
|
|
|
* 1=>поле в таблице |
|
|
|
|
|
|
|
* 2=>чему равно |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param array $array |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function removeRows($array) { |
|
|
|
|
|
|
|
foreach ($array as $task) { |
|
|
|
|
|
|
|
$this->query("DELETE FROM ?n WHERE ?n = ?i", $task[0], $task[1], $task[2]); |
|
|
|
|
|
|
|
//$wpdb->delete($task[0], array($task[1] => $task[2])); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class SafeMySQL |
|
|
|
/** |
|
|
|
{ |
|
|
|
* Возвращает sql для объединения таблиц |
|
|
|
|
|
|
|
* Принимает массива вида |
|
|
|
|
|
|
|
* array(array('name'=>'table1','field'=>'field1'),array('name'=>'table2','field'=>'field2')); |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param string $sql |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function selectLeftJoin($tables) { |
|
|
|
|
|
|
|
$sql = "SELECT * FROM `" . $tables . "`"; |
|
|
|
|
|
|
|
foreach ($ons as $k => $table) { |
|
|
|
|
|
|
|
$sql .= " LEFT JOIN `" . $table[0]['name'] . "` ON `" . $table[1]['name'] . "`.`" . $table[1]['field'] . "`=`" . $table[0]['name'] . "`.`" . $table[0]['field'] . "`"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return $sql; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Возвращает стандартную функцию обновления |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return string UPDATE ?n SET ?u WHERE `id` = ?i |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function updTempl() { |
|
|
|
|
|
|
|
return "UPDATE ?n SET ?u WHERE `id` = ?i"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Возвращает стандартную функцию вставки |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return string INSERT INTO ?n SET ?u |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function insTempl() { |
|
|
|
|
|
|
|
return "INSERT INTO ?n SET ?u"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
############################################################ |
|
|
|
|
|
|
|
|
|
|
|
protected $conn; |
|
|
|
protected $conn; |
|
|
|
protected $stats; |
|
|
|
protected $stats; |
|
|
|
protected $emode; |
|
|
|
protected $emode; |
|
|
|
protected $exname; |
|
|
|
protected $exname; |
|
|
|
|
|
|
|
|
|
|
|
protected $defaults = array( |
|
|
|
protected $defaults = array( |
|
|
|
'host' => 'localhost', |
|
|
|
'host' => 'localhost', |
|
|
|
'user' => 'root', |
|
|
|
'user' => 'root', |
|
|
@ -90,34 +139,28 @@ class SafeMySQL |
|
|
|
const RESULT_ASSOC = MYSQLI_ASSOC; |
|
|
|
const RESULT_ASSOC = MYSQLI_ASSOC; |
|
|
|
const RESULT_NUM = MYSQLI_NUM; |
|
|
|
const RESULT_NUM = MYSQLI_NUM; |
|
|
|
|
|
|
|
|
|
|
|
function __construct($opt = array()) |
|
|
|
function __construct($opt = array()) { |
|
|
|
{ |
|
|
|
|
|
|
|
$opt = array_merge($this->defaults, $opt); |
|
|
|
$opt = array_merge($this->defaults, $opt); |
|
|
|
|
|
|
|
|
|
|
|
$this->emode = $opt['errmode']; |
|
|
|
$this->emode = $opt['errmode']; |
|
|
|
$this->exname = $opt['exception']; |
|
|
|
$this->exname = $opt['exception']; |
|
|
|
|
|
|
|
|
|
|
|
if (isset($opt['mysqli'])) |
|
|
|
if (isset($opt['mysqli'])) { |
|
|
|
{ |
|
|
|
if ($opt['mysqli'] instanceof mysqli) { |
|
|
|
if ($opt['mysqli'] instanceof mysqli) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$this->conn = $opt['mysqli']; |
|
|
|
$this->conn = $opt['mysqli']; |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
$this->error("mysqli option must be valid instance of mysqli class"); |
|
|
|
$this->error("mysqli option must be valid instance of mysqli class"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ($opt['pconnect']) |
|
|
|
if ($opt['pconnect']) { |
|
|
|
{ |
|
|
|
|
|
|
|
$opt['host'] = "p:" . $opt['host']; |
|
|
|
$opt['host'] = "p:" . $opt['host']; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@$this->conn = mysqli_connect($opt['host'], $opt['user'], $opt['pass'], $opt['db'], $opt['port'], $opt['socket']); |
|
|
|
@$this->conn = mysqli_connect($opt['host'], $opt['user'], $opt['pass'], $opt['db'], $opt['port'], $opt['socket']); |
|
|
|
if ( !$this->conn ) |
|
|
|
if (!$this->conn) { |
|
|
|
{ |
|
|
|
|
|
|
|
$this->error(mysqli_connect_errno() . " " . mysqli_connect_error()); |
|
|
|
$this->error(mysqli_connect_errno() . " " . mysqli_connect_error()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -135,8 +178,7 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return resource|FALSE whatever mysqli_query returns |
|
|
|
* @return resource|FALSE whatever mysqli_query returns |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function query() |
|
|
|
public function query() { |
|
|
|
{ |
|
|
|
|
|
|
|
return $this->rawQuery($this->prepareQuery(func_get_args())); |
|
|
|
return $this->rawQuery($this->prepareQuery(func_get_args())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -147,8 +189,7 @@ class SafeMySQL |
|
|
|
* @param int $mode - optional fetch mode, RESULT_ASSOC|RESULT_NUM, default RESULT_ASSOC |
|
|
|
* @param int $mode - optional fetch mode, RESULT_ASSOC|RESULT_NUM, default RESULT_ASSOC |
|
|
|
* @return array|FALSE whatever mysqli_fetch_array returns |
|
|
|
* @return array|FALSE whatever mysqli_fetch_array returns |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function fetch($result,$mode=self::RESULT_ASSOC) |
|
|
|
public function fetch($result, $mode = self::RESULT_ASSOC) { |
|
|
|
{ |
|
|
|
|
|
|
|
return mysqli_fetch_array($result, $mode); |
|
|
|
return mysqli_fetch_array($result, $mode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -157,8 +198,7 @@ class SafeMySQL |
|
|
|
* |
|
|
|
* |
|
|
|
* @return int whatever mysqli_affected_rows returns |
|
|
|
* @return int whatever mysqli_affected_rows returns |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function affectedRows() |
|
|
|
public function affectedRows() { |
|
|
|
{ |
|
|
|
|
|
|
|
return mysqli_affected_rows($this->conn); |
|
|
|
return mysqli_affected_rows($this->conn); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -167,8 +207,7 @@ class SafeMySQL |
|
|
|
* |
|
|
|
* |
|
|
|
* @return int whatever mysqli_insert_id returns |
|
|
|
* @return int whatever mysqli_insert_id returns |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function insertId() |
|
|
|
public function insertId() { |
|
|
|
{ |
|
|
|
|
|
|
|
return mysqli_insert_id($this->conn); |
|
|
|
return mysqli_insert_id($this->conn); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -178,16 +217,14 @@ class SafeMySQL |
|
|
|
* @param resource $result - myqli result |
|
|
|
* @param resource $result - myqli result |
|
|
|
* @return int whatever mysqli_num_rows returns |
|
|
|
* @return int whatever mysqli_num_rows returns |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function numRows($result) |
|
|
|
public function numRows($result) { |
|
|
|
{ |
|
|
|
|
|
|
|
return mysqli_num_rows($result); |
|
|
|
return mysqli_num_rows($result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Conventional function to free the resultset. |
|
|
|
* Conventional function to free the resultset. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function free($result) |
|
|
|
public function free($result) { |
|
|
|
{ |
|
|
|
|
|
|
|
mysqli_free_result($result); |
|
|
|
mysqli_free_result($result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -202,11 +239,9 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return string|FALSE either first column of the first row of resultset or FALSE if none found |
|
|
|
* @return string|FALSE either first column of the first row of resultset or FALSE if none found |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getOne() |
|
|
|
public function getOne() { |
|
|
|
{ |
|
|
|
|
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
if ($res = $this->rawQuery($query)) |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
{ |
|
|
|
|
|
|
|
$row = $this->fetch($res); |
|
|
|
$row = $this->fetch($res); |
|
|
|
if (is_array($row)) { |
|
|
|
if (is_array($row)) { |
|
|
|
return reset($row); |
|
|
|
return reset($row); |
|
|
@ -227,8 +262,7 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return array|FALSE either associative array contains first row of resultset or FALSE if none found |
|
|
|
* @return array|FALSE either associative array contains first row of resultset or FALSE if none found |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getRow() |
|
|
|
public function getRow() { |
|
|
|
{ |
|
|
|
|
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
$ret = $this->fetch($res); |
|
|
|
$ret = $this->fetch($res); |
|
|
@ -249,14 +283,11 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return array|FALSE either enumerated array of first fields of all rows of resultset or FALSE if none found |
|
|
|
* @return array|FALSE either enumerated array of first fields of all rows of resultset or FALSE if none found |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getCol() |
|
|
|
public function getCol() { |
|
|
|
{ |
|
|
|
|
|
|
|
$ret = array(); |
|
|
|
$ret = array(); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
if ( $res = $this->rawQuery($query) ) |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
{ |
|
|
|
while ($row = $this->fetch($res)) { |
|
|
|
while($row = $this->fetch($res)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$ret[] = reset($row); |
|
|
|
$ret[] = reset($row); |
|
|
|
} |
|
|
|
} |
|
|
|
$this->free($res); |
|
|
|
$this->free($res); |
|
|
@ -275,14 +306,11 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return array enumerated 2d array contains the resultset. Empty if no rows found. |
|
|
|
* @return array enumerated 2d array contains the resultset. Empty if no rows found. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getAll() |
|
|
|
public function getAll() { |
|
|
|
{ |
|
|
|
|
|
|
|
$ret = array(); |
|
|
|
$ret = array(); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
$query = $this->prepareQuery(func_get_args()); |
|
|
|
if ( $res = $this->rawQuery($query) ) |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
{ |
|
|
|
while ($row = $this->fetch($res)) { |
|
|
|
while($row = $this->fetch($res)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$ret[] = $row; |
|
|
|
$ret[] = $row; |
|
|
|
} |
|
|
|
} |
|
|
|
$this->free($res); |
|
|
|
$this->free($res); |
|
|
@ -302,17 +330,14 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return array - associative 2d array contains the resultset. Empty if no rows found. |
|
|
|
* @return array - associative 2d array contains the resultset. Empty if no rows found. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getInd() |
|
|
|
public function getInd() { |
|
|
|
{ |
|
|
|
|
|
|
|
$args = func_get_args(); |
|
|
|
$args = func_get_args(); |
|
|
|
$index = array_shift($args); |
|
|
|
$index = array_shift($args); |
|
|
|
$query = $this->prepareQuery($args); |
|
|
|
$query = $this->prepareQuery($args); |
|
|
|
|
|
|
|
|
|
|
|
$ret = array(); |
|
|
|
$ret = array(); |
|
|
|
if ( $res = $this->rawQuery($query) ) |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
{ |
|
|
|
while ($row = $this->fetch($res)) { |
|
|
|
while($row = $this->fetch($res)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$ret[$row[$index]] = $row; |
|
|
|
$ret[$row[$index]] = $row; |
|
|
|
} |
|
|
|
} |
|
|
|
$this->free($res); |
|
|
|
$this->free($res); |
|
|
@ -331,17 +356,14 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the query |
|
|
|
* @return array - associative array contains key=value pairs out of resultset. Empty if no rows found. |
|
|
|
* @return array - associative array contains key=value pairs out of resultset. Empty if no rows found. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getIndCol() |
|
|
|
public function getIndCol() { |
|
|
|
{ |
|
|
|
|
|
|
|
$args = func_get_args(); |
|
|
|
$args = func_get_args(); |
|
|
|
$index = array_shift($args); |
|
|
|
$index = array_shift($args); |
|
|
|
$query = $this->prepareQuery($args); |
|
|
|
$query = $this->prepareQuery($args); |
|
|
|
|
|
|
|
|
|
|
|
$ret = array(); |
|
|
|
$ret = array(); |
|
|
|
if ( $res = $this->rawQuery($query) ) |
|
|
|
if ($res = $this->rawQuery($query)) { |
|
|
|
{ |
|
|
|
while ($row = $this->fetch($res)) { |
|
|
|
while($row = $this->fetch($res)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$key = $row[$index]; |
|
|
|
$key = $row[$index]; |
|
|
|
unset($row[$index]); |
|
|
|
unset($row[$index]); |
|
|
|
$ret[$key] = reset($row); |
|
|
|
$ret[$key] = reset($row); |
|
|
@ -373,8 +395,7 @@ class SafeMySQL |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the expression |
|
|
|
* @param mixed $arg,... unlimited number of arguments to match placeholders in the expression |
|
|
|
* @return string - initial expression with placeholders substituted with data. |
|
|
|
* @return string - initial expression with placeholders substituted with data. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function parse() |
|
|
|
public function parse() { |
|
|
|
{ |
|
|
|
|
|
|
|
return $this->prepareQuery(func_get_args()); |
|
|
|
return $this->prepareQuery(func_get_args()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -398,8 +419,7 @@ class SafeMySQL |
|
|
|
* @param string $default - optional variable to set if no match found. Default to false. |
|
|
|
* @param string $default - optional variable to set if no match found. Default to false. |
|
|
|
* @return string|FALSE - either sanitized value or FALSE |
|
|
|
* @return string|FALSE - either sanitized value or FALSE |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function whiteList($input,$allowed,$default=FALSE) |
|
|
|
public function whiteList($input, $allowed, $default = FALSE) { |
|
|
|
{ |
|
|
|
|
|
|
|
$found = array_search($input, $allowed); |
|
|
|
$found = array_search($input, $allowed); |
|
|
|
return ($found === FALSE) ? $default : $allowed[$found]; |
|
|
|
return ($found === FALSE) ? $default : $allowed[$found]; |
|
|
|
} |
|
|
|
} |
|
|
@ -420,12 +440,9 @@ class SafeMySQL |
|
|
|
* @param array $allowed - an array with allowed field names |
|
|
|
* @param array $allowed - an array with allowed field names |
|
|
|
* @return array filtered out source array |
|
|
|
* @return array filtered out source array |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function filterArray($input,$allowed) |
|
|
|
public function filterArray($input, $allowed) { |
|
|
|
{ |
|
|
|
foreach (array_keys($input) as $key) { |
|
|
|
foreach(array_keys($input) as $key ) |
|
|
|
if (!in_array($key, $allowed)) { |
|
|
|
{ |
|
|
|
|
|
|
|
if ( !in_array($key,$allowed) ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
unset($input[$key]); |
|
|
|
unset($input[$key]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -437,8 +454,7 @@ class SafeMySQL |
|
|
|
* |
|
|
|
* |
|
|
|
* @return string|NULL either last executed query or NULL if were none |
|
|
|
* @return string|NULL either last executed query or NULL if were none |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function lastQuery() |
|
|
|
public function lastQuery() { |
|
|
|
{ |
|
|
|
|
|
|
|
$last = end($this->stats); |
|
|
|
$last = end($this->stats); |
|
|
|
return $last['query']; |
|
|
|
return $last['query']; |
|
|
|
} |
|
|
|
} |
|
|
@ -448,8 +464,7 @@ class SafeMySQL |
|
|
|
* |
|
|
|
* |
|
|
|
* @return array contains all executed queries with timings and errors |
|
|
|
* @return array contains all executed queries with timings and errors |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function getStats() |
|
|
|
public function getStats() { |
|
|
|
{ |
|
|
|
|
|
|
|
return $this->stats; |
|
|
|
return $this->stats; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -460,8 +475,7 @@ class SafeMySQL |
|
|
|
* @param string $query - a regular SQL query |
|
|
|
* @param string $query - a regular SQL query |
|
|
|
* @return mysqli result resource or FALSE on error |
|
|
|
* @return mysqli result resource or FALSE on error |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected function rawQuery($query) |
|
|
|
protected function rawQuery($query) { |
|
|
|
{ |
|
|
|
|
|
|
|
$start = microtime(TRUE); |
|
|
|
$start = microtime(TRUE); |
|
|
|
$res = mysqli_query($this->conn, $query); |
|
|
|
$res = mysqli_query($this->conn, $query); |
|
|
|
$timer = microtime(TRUE) - $start; |
|
|
|
$timer = microtime(TRUE) - $start; |
|
|
@ -471,8 +485,7 @@ class SafeMySQL |
|
|
|
'start' => $start, |
|
|
|
'start' => $start, |
|
|
|
'timer' => $timer, |
|
|
|
'timer' => $timer, |
|
|
|
); |
|
|
|
); |
|
|
|
if (!$res) |
|
|
|
if (!$res) { |
|
|
|
{ |
|
|
|
|
|
|
|
$error = mysqli_error($this->conn); |
|
|
|
$error = mysqli_error($this->conn); |
|
|
|
|
|
|
|
|
|
|
|
end($this->stats); |
|
|
|
end($this->stats); |
|
|
@ -486,29 +499,24 @@ class SafeMySQL |
|
|
|
return $res; |
|
|
|
return $res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function prepareQuery($args) |
|
|
|
protected function prepareQuery($args) { |
|
|
|
{ |
|
|
|
|
|
|
|
$query = ''; |
|
|
|
$query = ''; |
|
|
|
$raw = array_shift($args); |
|
|
|
$raw = array_shift($args); |
|
|
|
$array = preg_split('~(\?[nsiuap])~u', $raw, null, PREG_SPLIT_DELIM_CAPTURE); |
|
|
|
$array = preg_split('~(\?[nsiuap])~u', $raw, null, PREG_SPLIT_DELIM_CAPTURE); |
|
|
|
$anum = count($args); |
|
|
|
$anum = count($args); |
|
|
|
$pnum = floor(count($array) / 2); |
|
|
|
$pnum = floor(count($array) / 2); |
|
|
|
if ( $pnum != $anum ) |
|
|
|
if ($pnum != $anum) { |
|
|
|
{ |
|
|
|
|
|
|
|
$this->error("Number of args ($anum) doesn't match number of placeholders ($pnum) in [$raw]"); |
|
|
|
$this->error("Number of args ($anum) doesn't match number of placeholders ($pnum) in [$raw]"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
foreach ($array as $i => $part) |
|
|
|
foreach ($array as $i => $part) { |
|
|
|
{ |
|
|
|
if (($i % 2) == 0) { |
|
|
|
if ( ($i % 2) == 0 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$query .= $part; |
|
|
|
$query .= $part; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$value = array_shift($args); |
|
|
|
$value = array_shift($args); |
|
|
|
switch ($part) |
|
|
|
switch ($part) { |
|
|
|
{ |
|
|
|
|
|
|
|
case '?n': |
|
|
|
case '?n': |
|
|
|
$part = $this->escapeIdent($value); |
|
|
|
$part = $this->escapeIdent($value); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -533,90 +541,72 @@ class SafeMySQL |
|
|
|
return $query; |
|
|
|
return $query; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function escapeInt($value) |
|
|
|
protected function escapeInt($value) { |
|
|
|
{ |
|
|
|
if ($value === NULL) { |
|
|
|
if ($value === NULL) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return 'NULL'; |
|
|
|
return 'NULL'; |
|
|
|
} |
|
|
|
} |
|
|
|
if(!is_numeric($value)) |
|
|
|
if (!is_numeric($value)) { |
|
|
|
{ |
|
|
|
|
|
|
|
$this->error("Integer (?i) placeholder expects numeric value, " . gettype($value) . " given"); |
|
|
|
$this->error("Integer (?i) placeholder expects numeric value, " . gettype($value) . " given"); |
|
|
|
return FALSE; |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
} |
|
|
|
if (is_float($value)) |
|
|
|
if (is_float($value)) { |
|
|
|
{ |
|
|
|
|
|
|
|
$value = number_format($value, 0, '.', ''); // may lose precision on big numbers |
|
|
|
$value = number_format($value, 0, '.', ''); // may lose precision on big numbers |
|
|
|
} |
|
|
|
} |
|
|
|
return $value; |
|
|
|
return $value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function escapeString($value) |
|
|
|
protected function escapeString($value) { |
|
|
|
{ |
|
|
|
if ($value === NULL) { |
|
|
|
if ($value === NULL) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return 'NULL'; |
|
|
|
return 'NULL'; |
|
|
|
} |
|
|
|
} |
|
|
|
return "'" . mysqli_real_escape_string($this->conn, $value) . "'"; |
|
|
|
return "'" . mysqli_real_escape_string($this->conn, $value) . "'"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function escapeIdent($value) |
|
|
|
protected function escapeIdent($value) { |
|
|
|
{ |
|
|
|
if ($value) { |
|
|
|
if ($value) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return "`" . str_replace("`", "``", $value) . "`"; |
|
|
|
return "`" . str_replace("`", "``", $value) . "`"; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$this->error("Empty value for identifier (?n) placeholder"); |
|
|
|
$this->error("Empty value for identifier (?n) placeholder"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function createIN($data) |
|
|
|
protected function createIN($data) { |
|
|
|
{ |
|
|
|
if (!is_array($data)) { |
|
|
|
if (!is_array($data)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$this->error("Value for IN (?a) placeholder should be array"); |
|
|
|
$this->error("Value for IN (?a) placeholder should be array"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!$data) |
|
|
|
if (!$data) { |
|
|
|
{ |
|
|
|
|
|
|
|
return 'NULL'; |
|
|
|
return 'NULL'; |
|
|
|
} |
|
|
|
} |
|
|
|
$query = $comma = ''; |
|
|
|
$query = $comma = ''; |
|
|
|
foreach ($data as $value) |
|
|
|
foreach ($data as $value) { |
|
|
|
{ |
|
|
|
|
|
|
|
$query .= $comma . $this->escapeString($value); |
|
|
|
$query .= $comma . $this->escapeString($value); |
|
|
|
$comma = ","; |
|
|
|
$comma = ","; |
|
|
|
} |
|
|
|
} |
|
|
|
return $query; |
|
|
|
return $query; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function createSET($data) |
|
|
|
protected function createSET($data) { |
|
|
|
{ |
|
|
|
if (!is_array($data)) { |
|
|
|
if (!is_array($data)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$this->error("SET (?u) placeholder expects array, " . gettype($data) . " given"); |
|
|
|
$this->error("SET (?u) placeholder expects array, " . gettype($data) . " given"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!$data) |
|
|
|
if (!$data) { |
|
|
|
{ |
|
|
|
|
|
|
|
$this->error("Empty array for SET (?u) placeholder"); |
|
|
|
$this->error("Empty array for SET (?u) placeholder"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
$query = $comma = ''; |
|
|
|
$query = $comma = ''; |
|
|
|
foreach ($data as $key => $value) |
|
|
|
foreach ($data as $key => $value) { |
|
|
|
{ |
|
|
|
|
|
|
|
$query .= $comma . $this->escapeIdent($key) . '=' . $this->escapeString($value); |
|
|
|
$query .= $comma . $this->escapeIdent($key) . '=' . $this->escapeString($value); |
|
|
|
$comma = ","; |
|
|
|
$comma = ","; |
|
|
|
} |
|
|
|
} |
|
|
|
return $query; |
|
|
|
return $query; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function error($err) |
|
|
|
protected function error($err) { |
|
|
|
{ |
|
|
|
|
|
|
|
$err = __CLASS__ . ": " . $err; |
|
|
|
$err = __CLASS__ . ": " . $err; |
|
|
|
|
|
|
|
|
|
|
|
if ( $this->emode == 'error' ) |
|
|
|
if ($this->emode == 'error') { |
|
|
|
{ |
|
|
|
|
|
|
|
$err .= ". Error initiated in " . $this->caller() . ", thrown"; |
|
|
|
$err .= ". Error initiated in " . $this->caller() . ", thrown"; |
|
|
|
trigger_error($err, E_USER_ERROR); |
|
|
|
trigger_error($err, E_USER_ERROR); |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -624,14 +614,11 @@ class SafeMySQL |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function caller() |
|
|
|
protected function caller() { |
|
|
|
{ |
|
|
|
|
|
|
|
$trace = debug_backtrace(); |
|
|
|
$trace = debug_backtrace(); |
|
|
|
$caller = ''; |
|
|
|
$caller = ''; |
|
|
|
foreach ($trace as $t) |
|
|
|
foreach ($trace as $t) { |
|
|
|
{ |
|
|
|
if (isset($t['class']) && $t['class'] == __CLASS__) { |
|
|
|
if ( isset($t['class']) && $t['class'] == __CLASS__ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$caller = $t['file'] . " on line " . $t['line']; |
|
|
|
$caller = $t['file'] . " on line " . $t['line']; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
@ -644,13 +631,12 @@ class SafeMySQL |
|
|
|
* On a long run we can eat up too much memory with mere statsistics |
|
|
|
* On a long run we can eat up too much memory with mere statsistics |
|
|
|
* Let's keep it at reasonable size, leaving only last 100 entries. |
|
|
|
* Let's keep it at reasonable size, leaving only last 100 entries. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected function cutStats() |
|
|
|
protected function cutStats() { |
|
|
|
{ |
|
|
|
if (count($this->stats) > 100) { |
|
|
|
if ( count($this->stats) > 100 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
reset($this->stats); |
|
|
|
reset($this->stats); |
|
|
|
$first = key($this->stats); |
|
|
|
$first = key($this->stats); |
|
|
|
unset($this->stats[$first]); |
|
|
|
unset($this->stats[$first]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|