I seem to have problem getting affected_rows when I INSERT and SELECT, it just returns -1 for some reason? I'm using a database class which I use all the time for my projects which uses MYSQLI prepare statements to avoid SQL injections.
Does anyone know why it returns -1 all the time? From what I have read it should be able to return affected rows on both INSERT and SELECT.
Database class
class database {
protected $_mysqli;
protected $_debug;
public function __construct($host, $username, $password, $database, $debug) {
$this->_mysqli = new mysqli($host, $username, $password, $database);
$this->_debug = (bool) $debug;
if (mysqli_connect_errno()) {
if ($this->_debug) {
echo mysqli_connect_error();
debug_print_backtrace();
}
return false;
}
return true;
}
public function q($query) {
if ($query = $this->_mysqli->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_merge(array(func_get_arg(1)),
array_slice($x, 2));
$args_ref = array();
foreach($args as $k => &$arg) {
$args_ref[$k] = &$arg;
}
call_user_func_array(array($query, 'bind_param'), $args_ref);
}
$query->execute();
if ($query->errno) {
if ($this->_debug) {
echo mysqli_error($this->_mysqli);
debug_print_backtrace();
}
return false;
}
if ($query->affected_rows > -1) {
return $query->affected_rows;
}
$params = array();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($query, 'bind_result'), $params);
$result = array();
while ($query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
$result[] = $r;
}
$query->close();
return $result;
} else {
if ($this->_debug) {
echo $this->_mysqli->error;
debug_print_backtrace();
}
return false;
}
}
public function handle() {
return $this->_mysqli;
}
public function last_insert_id()
{
return $this->_mysqli->insert_id;
}
public function found_rowss()
{
return $this->_mysqli->affected_rows;
}
}
for Select-statements created with prepare you should use $query->num_rows()
or mysqli_stmt_num_rows($query)
.
The Insert-Statement may give you supressed errors when you do a "INSERT IGNORE"
which may lead to the -1 in $query->affected_rows()
.
A comment on php.net (second link) suggests you use $query->sqlstate=="00000"
to check for errors.
see php.net (manual/en/mysqli-stmt.affected-rows):
"This function only works with queries which update a table. In order to get the number of rows from a SELECT query, use mysqli_stmt_num_rows()
instead."
and php.net (manual/en/mysqli.affected-rows):
"Checking if mysqli->affected_rows will equal -1 or not is not a good method of determining success of "INSERT IGNORE"
statements. Example: Ignoring duplicate key errors while inserting some rows containing data provided by user only if they will match specified unique constraint causes returning of -1 value by mysqli->affected_rows
even if rows were inserted. (checked on MySQL 5.0.85 linux and php 5.2.9-2 windows). However mysqli->sqlstate
returns no error if statement was executed successfully."