13.Zend Framework 2 et 3
13.7.Les bases de données
13.7.5.Parcourir les résultats de la requête SQL
13.7.5.1.Introduction
Nous avons vu dans les chapitres précédents comment construire une requête SQL avec Zend Framework
[comment?], nous avons vu comment l'exécuter
[comment?]. Reste, dans le cas d'une requête SELECT, à voir comment parcourir les résultats de la requête. C'est l'objet de ce chapitre.
Que la requête ait été exécutée via la méthode
query() de la classe
Zend\Db\Adapter\Adapter ou
execute() d'un classe implémentant
Zend\Db\Apdater\Driver\StatementInterface le principe est le même, l'objet retourné est un itérateur (i.e. implémente l'interface
Iterator). Il est par conséquent possible, entre autres, de:
- Parcourir l'ensemble des éléments avec une boucle foreach
- Faire appel à la méthode current() pour récupérer l'élément sur lequel le pointeur est actuellement positionné
- Faire appel à la méthode next() pour passer à l'élément suivant (et le récupérer)
|
En revanche, c'est dans les détails que nous trouverons quelques différences puisque query() retourne un objet Zend\Db\ResultSet\ResultSet tandis que execute() retourne un objet Zend\Db\Adapter\Driver\ResultInterface.
13.7.5.2.Parcours avec foreach
Comme on peut le voir dans les exemples ci-dessous: Que ce soit avec
query()
<?php
// On supposera les variables $sql, $db, $nomTable, etc. définies précédemment
$requete = $sql->select($nomTable);
// La requête (objet Sql) sera convertie en chaîne de caractères
$sqlStr = $sql->buildSqlString($requete);
$lignes = $db->query($sqlStr, Adapter::QUERY_MODE_EXECUTE);
// Boucle sur l'ensemble des enregistrements
foreach ($lignes as $ligne) {
// $ligne contient les valeurs des différents champs d'un enregistrement retourné par la requête.
// Ainsi la valeur du champ 'monchamp' est disponible dans $ligne['monchamp'].
echo $ligne['monchamp']."\n";
}
ou avec
execute()
<?php
// On supposera les variables $sql, $db, $nomTable, etc. définies précédemment
$requete = $sql->select($nomTable);
// La requête (objet Sql) sera convertie en "requête préparée"
$stmt = $sql->prepareStatementForSqlObject($requete);
$lignes = $stmt->execute();
// Boucle sur l'ensemble des enregistrements
foreach ($lignes as $ligne) {
// $ligne contient les valeurs des différents champs d'un enregistrement retourné par la requête.
// Ainsi la valeur du champ 'monchamp' est disponible dans $ligne['monchamp'].
echo $ligne['monchamp']."\n";
}
la façon de parcourir l'ensemble des enregistrements avec foreach() est véritablement identique.
|
Attention toutefois, la nature des éléments parcourus diffère entre les 2 cas de figure. Dans le cas query() chaque élément rétourné par l'itérateur est un objet ArrayObject. Dans le cas execute() l'élément retourné est un simple tableau (type array). |
Dans les 2 cas, il est possible de récupérer la valeur d'un champ en utilisant l'élément retourné comme un simple tableau indexé (c'est à dire en précisant entre crochet le nom du champ pour lequel on souhaite connaitre la valeur associée) en revanche vous pourriez avoir des surprises en tentant d'appliquer, sur les résultats de
query() des fonctions habituellements utilisées sur des tableaux.
Si des fonctions comme
array_key_exists() peuvent s'appliquer à des objets
ArrayObject cela n'est pas (encore?) le cas, par exemple, de la fonction
array_keys()
13.7.5.3.Parcours avec current() et next()
Pour parcourir tout ou partie des enregistrements retourné par la requête il est également possible de faire appel à la fonction current() pour récupérer le premier resultat puis faire des appels successifs à next() pour les résultats suivants.
Comme expliqué dans le chapitre précédent (foreach) la nature des éléments retournés par l'itérateur diffère d'un cas à l'autre. Dans le cas query() c'est un ArrayObject qui est retourné, dans le cas execute() c'est un simple tableau (type array) qui est retourné. Les mêmes remarques s'appliquent donc.
L'autre différence majeure entre les 2 cas de figure concerne la valeur retour lorsque le dernier enregistrement a été atteint (ou plutôt dépassé). En effet, dans le cas query() l'itérateur retourne null alors que dans le cas execute() il retournera false.
Ce qui donne une boucle de parcours comme suit pour
query()
<?php
$requete = $sql->select($nomTable);
// La requête (objet Sql) sera convertie en chaîne de caractères
$sqlStr = $sql->buildSqlString($requete);
$lignes = $db->query($sqlStr, Adapter::QUERY_MODE_EXECUTE);
// Lecture du premier enregistrement
$ligne = $lignes->current();
while (null !== $ligne) {
// Tant qu'il y a effectivement un enregistrement (i.e !== null) on continue de parcourir
// les enregistrements.
// $ligne contient les valeurs des différents champs d'un enregistrement retourné par la requête.
// Ainsi la valeur du champ 'monchamp' est disponible dans $ligne['monchamp'].
echo $ligne['monchamp']."\n";
// on passe à l'enregistrement suivant
$ligne = $lignes->next();
}
et comme suit pour
execute()
<?php
$requete = $sql->select($nomTable);
// La requête (objet Sql) sera convertie en "requête préparée"
$stmt = $sql->prepareStatementForSqlObject($requete);
$lignes = $stmt->execute();
// Lecture du premier enregistrement
$ligne = $lignes->current();
while (false !== $ligne) {
// Tant qu'il y a effectivement un enregistrement (i.e !== false) on continue de parcourir
// les enregistrements.
// $ligne contient les valeurs des différents champs d'un enregistrement retourné par la requête.
// Ainsi la valeur du champ 'monchamp' est disponible dans $ligne['monchamp'].
echo $ligne['monchamp']."\n";
// on passe à l'enregistrement suivant
$ligne = $lignes->next();
}