Additional post tags should be: mysqli
spl
, but I'm too new on CR.
I've made a SPL-based class named MySQLi_Recordset that wraps both MySQLi_STMT and MySQLi_Result objects and allows treating either as a 3-dimensional array. It requires PHP5.3+.
This allows accessing result rows by array key (echo $recorset[295]['title'];
) or by foreach loops (foreach ($recordset as $rec) {echo $rec['title'];}
). Objects are created by passing in an sql query statement. For handling prepared statements, simply pass in additional arguments as the prepared binding parameters. In those cases, there is a behind-the-scenes bind_param
going on to generate the MySQLi_STMT object to be wrapped, but that part isn't included here. So for the purposes of this post, pretend it's magic.
For example to automatically handle the query as a prepared statement:
$recordset = new MySQLi_Recordset("SELECT * FROM tblComments WHERE(parentBlogID = ?)", 2);
foreach ($recordset as $record)
echo $record['commentText'] . '<br>';
The code is roughly 200 lines long, so instead of making a giant post, here's a pastebin link... http://pastebin.com/LUe4j9DM
Here's some speed tests using a localhost table with 6 columns. This test was done with prepared statement results either wrapped in MySQLi_Recordset or not...
10000 Records With MySQLi_Recordset...
foreach($MySQLi_Recordset as $rec) {$x = $rec;}
... 0.10179591178894 msfor ($i = 0, $count = count($MySQLi_Recordset); $i < $count; $i++) {$x = $MySQLi_Recordset[$i];}
... 0.055855989456177 msfor ($i = 0, $count = count($MySQLi_Recordset); $i < $count; $i++) {$x = $MySQLi_Recordset->fetchRow($i);}
... 0.039575099945068 ms
10000 Records Without MySQLi_Recordset still using the "bind to array" technique...
for ($i=0, $count=$MySQLI_STMT->num_rows; $i < $count; $i++)) {$MySQLI_STMT->fetch(); $x = $bind_row["commentID"];}
... 0.041354894638062 mswhile ($MySQLI_STMT->fetch()) {$x = $bind_row["commentID"];}
... 0.008719921112 0605 ms
I'm pretty bummed about the slow foreach loop over my MySQLi_Recordset object, and by the fact that nothing can even compare to while ($MySQLI_STMT->fetch()) {}
. I'd like for this to work, especially since it allows exchanging this class out for regular 3-dimensional arrays of result dumps easily and avoid duplication of binding code on every statement throughout an application. Any suggestions or criticisms?