I created the MySQLi query function below, and it works great with SELECT queries and does everything dynamically so it can work with result sets of any size, but when I try INSERT INTO, I get the message Fatal error: Call to a member function fetch_field() on boolean. I want it to return TRUE or FALSE for queries like INSERT INTO, UPDATE, etc. based on if the query was successful or not. Any suggestions?
Here's the full query function:
/**
* Querying the database
*
* @param string $query_string The query string to be executed
* @param array $params The parameters for the query if it is a prepared statement
*
* @return mixed The results of the query, either in an array or NULL, or FALSE if executing the query failed
*/
final public function query($query_string, $params = array()) {
// Resetting error and result data
$this->error = FALSE;
$this->result = array();
$this->result_metadata = array();
// Initiating the query statement
$this->stmt = $this->DB->stmt_init();
// Preparing the query statement and binding parameters if provided
if ($this->stmt->prepare($query_string) and count($params)) {
// Setting the types of each parameter in $params
$param_types = "";
foreach ($params as $param) {
if (is_int($param)) {
$param_types .= "i"; continue;
}
if (is_float($param)) {
$param_types .= "d"; continue;
}
if (is_string($param)) {
$param_types .= "s"; continue;
}
else {
$param_types .= "b";
}
}
// Appending the parameter types to the beginning of $params for use in call_user_func_array
array_unshift($params, $param_types);
// Creating a reference array and passing all values from $params into it by reference
$reference = array();
foreach ($params as $key => $param) {
$reference[$key] = &$params[$key];
}
// Binding the parameters to the query statement
call_user_func_array(array($this->stmt, "bind_param"), $reference);
}
// Executing the query statement
if (@$this->stmt->execute()) {
// Fetching the metadata of the result
$this->result_metadata = $this->stmt->result_metadata();
// Populating $fields with variables whose name is the value of $field_name indexed under $field_name
while ($field = $this->result_metadata->fetch_field()) {
$field_name = $field->name;
$$field_name = NULL;
$fields[$field_name] = &$$field_name;
}
// Binding the results of the query to $fields
call_user_func_array(array($this->stmt, "bind_result"), $fields);
// Storing the results of the query
$this->stmt->store_result();
// Fetching the results of the query and storing them in $result_array
$row = 0;
while ($this->stmt->fetch()) {
$result_array[$row] = array();
foreach ($fields as $key => $field) {
$result_array[$row][$key] = $field;
}
$row++;
}
// Storing the number of rows to self::$num_rows
$this->num_rows = $this->stmt->num_rows;
// Closing the query statement
$this->stmt->free_result();
$this->stmt->close();
// Returning $result_array, or the only element of $result_array if $result_array is of size 1
return @((count($result_array) === 1) ? $result_array[0] : $result_array);
}
// Setting $this->error equal to the DB error and returning FALSE
else {
$this->error = $this->DB->error;
return FALSE;
}
}