Les doubles itérations
Voici un exemple de code que je trouve souvent dans du code de projet open source ou projet que je reprends :
// $rResult = mysql_query( "SELECT id, firstName, lastName ". "FROM user" ); // Itération #1 $aRecordSet = array(); while($aRow = mysql_fetch_assoc($rResult)) { $aRecordSet[] = $aRow; } // Itération #2 foreach($aRecordSet as $aRow) { echo $aRow['firstNAme']; echo $aRow['lastNAme']; }
Ce n'est qu'une figure de style, car souvent le concept objet est utilisé et les gens crée une méthode qui ressemble à $aAllRow = $oRecordset->fetch_allrow(); où l'itération #1 est encapsulé dans celle-çi donc c'est dans cette méthode que se retrouve la première itération. Et par la suite cette fonction est utilisée presque partout dans le projet.
Pour en revenir à l'exemple, dans ce code il y a une double itération pour afficher le résultat de la requête. Une pour la construction du tableau qui contient va contenir tous les enregistrements et une autre pour afficher les enregistrements de celui-ci.
Le problème est que la ressource $rResult pointe déjà sur un espace mémoire PHP qui contient soit le recordset en entier ou simplement une interface entre PHP et MySQL pour aller cherche les enregistrements un à la fois sur MySQL. Donc le fait de faire la première boucle pour construite un tableau revient à faire une copie des données du recordset dans une partie de la mémoire de PHP. Dans certains cas, nous avons même une double utilisation de la mémoire.
Résultat : Nous avons une perte de mémoire ainsi qu'une perte de cycle CPU.
Dans tous les cas, l'utilisation du recordset directement est beaucoup plus optimise que celui d'un array. Donc pour faire la même chose il serait préférable de faire l'opération de cette façon :
// $rResult = mysql_query( "SELECT firstName, lastName FROM user" ); $aRecordSet = array(); while($aRow = mysql_fetch_assoc($rResult)) { echo $aRow['firstNAme']; echo $aRow['lastNAme']; }
Ou en orienté objet (MySQLI) :
// $oRecordset = $oDb->query( "SELECT firstName, lastName FROM user" ); while($aRow = $oRecordset->fetch_assoc()) { echo $aRow['firstNAme']; echo $aRow['lastNAme']; }