The next_result() function plays a crucial role when handling multi-statement queries using PHP and MySQL's mysqli extension. It allows you to fetch multiple result sets in sequence, but sometimes you may encounter various unexpected problems when switching result sets, such as "Commands out of sync; you can't run this command now". This article will introduce how to locate and troubleshoot problems related to the next_result() function through logging.
mysqli::multi_query() allows you to send multiple SQL statements in a query, while next_result() is used to traverse these result sets in turn. For example:
$mysqli = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT * FROM users; SELECT * FROM orders;";
if ($mysqli->multi_query($sql)) {
do {
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$result->free();
}
} while ($mysqli->next_result());
} else {
error_log("Query failed: " . $mysqli->error);
}
If next_result() is not called correctly or an error occurs in the middle, it will cause an exception to the connection state.
Error message: "Commands out of sync; you can't run this command now"
Query interrupted, the result is incomplete
Unable to continue executing the next SQL
Most of these problems are related to the fact that the result is not fully processed or the call to next_result() is not called.
To troubleshoot problems, we can log the log at each step and track the call process and status. It is recommended to use error_log() to write to log files:
function log_step($message) {
$logFile = '/var/log/php_next_result_debug.log';
error_log(date("[Y-m-d H:i:s] ") . $message . PHP_EOL, 3, $logFile);
}
In combination with the query example above, we add log output:
$sql = "SELECT * FROM users; SELECT * FROM orders;";
if ($mysqli->multi_query($sql)) {
log_step("Multi-query started.");
do {
if ($result = $mysqli->store_result()) {
log_step("Result set retrieved.");
while ($row = $result->fetch_assoc()) {
log_step("Row: " . json_encode($row));
}
$result->free();
} elseif ($mysqli->errno) {
log_step("Error during store_result: " . $mysqli->error);
}
log_step("Calling next_result()...");
} while ($mysqli->next_result());
log_step("All result sets processed.");
} else {
log_step("Multi-query failed: " . $mysqli->error);
}
If more detailed tracking is required, SQL content, execution time, and status code can be recorded at each SQL execution point. In addition, logs can be centrally managed visually, such as by sending them to ELK, Graylog, or self-built logging platforms.
log_step("SQL Executed: " . $sql . " on https://gitbox.net/db-query-monitor");
Always process all result sets and call next_result() .
Use logs to record every key step for easy post-temptation.
Do not ignore mysqli::error and mysqli::errno when an exception occurs.
It can encapsulate a unified multi-query execution function with built-in log logic for easy reuse.