Multi-queries open the potential for a SQL injection.
The often cited "fallback" loop:
<?php
while ( $db->more_results() and $db->next_result() ) {
$rs = $db->use_result();
if( $rs instanceof \mysqli_result ) {
$rs->free();
}
?>
certainly will avoid the dreaded error 2014 "Commands out of sync; you can't run this command now" error. However, that technique will completely disregard the fact that any excess result sets are a likely indication of an infiltrated system.
Instead, it may be wise to tightly manage the correct number of expected, individual result sets and throw an exception of more are received.
However, it's important to understand that any closing comment (which might have been appended as one defense against command appending) will result in an EXTRA, EMPTY result set.
Example:
SELECT SQL_CALC_FOUND_ROWS * FROM `table` LIMIT 10; SELECT FOUND_ROWS(); --
will produce THREE result sets:
#1 - the ten data rows,
#2 - the overall row count,
#3 - an empty result set, where: FALSE === $db->use_result(), even though it had been TRUE === ($db->more_results() and $db->next_result() ) .