Zend_Db_Table_Rowset
Introduction
Lorsque vous effectuez une requête avec une classe de Table en utilisant
find() ou fetchAll() , le résultat retourné est alors un objet
de type Zend_Db_Table_Rowset_Abstract. Un Rowset est un conteneur
d'objets descendants de Zend_Db_Table_Row_Abstract. Vous pouvez
itérer à travers ce conteneur et accéder aux objet Row individuellement, en lecture ou
écriture bien entendu.
Récupérer un Rowset
Zend_Db_Table_Abstract possède des méthodes
find() et fetchAll(), chacune retourne un objet de type
Zend_Db_Table_Rowset_Abstract.
Exemple de récupération d'un rowset
fetchAll("bug_status = 'NEW'");
]]>
Atteindre les Rows depuis un Rowset
L'objet Rowset en lui-même n'est pas très intéressant au regard des objets Rows
qu'il contient, qui eux, le sont bien plus.
Un requête légitime peut retourner zéro enregistrement, donc zéro Rows. De ce
fait, un objet Rowset peut contenir zéro objet Row. Comme
Zend_Db_Table_Rowset_Abstract implémente l'interface
Countable, vous pouvez utiliser la fonction PHP count()
dessus, pour compter les Rows qu'il contient.
Compter les Rows dans un Rowset
fetchAll("bug_status = 'FIXED'");
$rowCount = count($rowset);
if ($rowCount > 0) {
echo "$rowCount rows trouvés";
} else {
echo 'Pas de rows pour cette requête';
}
]]>
Lecture d'un simple Row depuis un Rowset
La façon la plus simple d'accéder à un Row depuis l'objet Rowset est
d'utiliser la méthode current(). C'est tout à fait adapté lorsque le
Rowset ne contient qu'un résultat (Row).
fetchAll("bug_id = 1");
$row = $rowset->current();
]]>
Si le Rowset ne contient aucun Row, current() retourne
NULL.
Itération à travers un Rowset
Les objets descendants de Zend_Db_Table_Rowset_Abstract
implémentent l'interface Iterator, ce qui veut dire qu'ils peuvent être
utilisés dans la structure PHP foreach. Chaque valeur récupérée
représente alors un objet de Zend_Db_Table_Row_Abstract qui
correspond à un enregistrement dans la table.
fetchAll();
foreach ($rowset as $row) {
// affiche 'Zend_Db_Table_Row' par défaut
echo get_class($row) . "\n";
// lit une colonne dans le résultat Row
$status = $row->bug_status;
// modifie une colonne dans le résultat courant
$row->assigned_to = 'mmouse';
// Enregistre en base de données
$row->save();
}
]]>
Déplacement vers une position précise dans le Rowset
SeekableIterator vous permet de vus déplacer à une position
précise dans l'itérateur. Utilisez pour ceci la méthode seek(). Elle
prend en paramètre un entier représentant le numéro de la position désirée.
N'oubliez pas que le premier enregistrement est stocké à la position zéro. Si vous
spécifiez une position qui n'existe pas, une exception sera levée. Vous devriez
utiliser count() pour vérifier le nombre d'enregistrements Rows
présents.
fetchAll();
// Déplace l'itérateur à l'enregistrement 8 (le neuvième donc) :
$rowset->seek(8);
// récupèration de cet enregistrement
$row9 = $rowset->current();
// et utilisation
$row9->assigned_to = 'mmouse';
$row9->save();
]]>
getRow() permet de retourner directement un enregistrement en
fonction de sa position dans l'itérateur Rowset. Le premier paramètre est un entier
représentant cette position. Le second paramètre est optionnel, et indique si oui ou non
l'itérateur doit rester sur cette position, après avoir retourné le Row correspondant.
Par défaut, il est à FALSE. Cette méthode retourne donc un objet
Zend_Db_Table_Row. Si la position demandée n'existe pas, une
exception est levée :
fetchAll();
// récupère le neuvième enregistrement immédiatement
$row9 = $rowset->getRow(8);
// utilisation de l'enregistrement récupéré :
$row9->assigned_to = 'mmouse';
$row9->save();
]]>
Dès que vous avez accès à un objet individuel Row, vous pouvez le piloter comme
présenté dans la section .
Récupérer un Rowset en tant que tableau (Array)
Vous pouvez accéder à toutes les données d'un Rowset au moyen d'un tableau PHP
avec la méthode toArray(). Ce tableau possède deux dimensions. Chaque
entrée du tableau représente un tableau de l'objet Row. Les clés sont les noms des
champs, et les valeurs leurs valeurs.
Utiliser toArray()
fetchAll();
$rowsetArray = $rowset->toArray();
$rowCount = 1;
foreach ($rowsetArray as $rowArray) {
echo "row #$rowCount:\n";
foreach ($rowArray as $column => $value) {
echo "\t$column => $value\n";
}
++$rowCount;
echo "\n";
}
]]>
Le tableau retourné par toArray() n'est pas une référence. Le
modifier ne modifiera en aucun cas les données réelles dans la base de données.
Sérialisation et Désérialisation d'un Rowset
Les objets de type Zend_Db_Table_Rowset_Abstract sont
sérialisables. De la même manière que vous sérialisez un objet Row individuel, le Rowset
est sérialisable et désérialisable.
Sérialiser d'un Rowset
Utilisez simplement la fonction PHP serialize() pour créer une
chaîne de caractères représentant votre objet Rowset.
fetchAll();
// Convertit l'objet en sa forme sérialisée
$serializedRowset = serialize($rowset);
// Maintenant vous pouvez écrire $serializedRowset
// dans un fichier, etc.
]]>
Désérialisation d'un objet Rowset sérialisé
Utilisez simplement la fonction PHP unserialize().
Notez que l'objet retourné fonctionne alors en mode
déconnecté. Vous pouvez itérer à travers, et lire les objets
Row qu'il contient, mais vous ne pouvez plus faire intervenir la base de données, ni
changer de valeurs dans les Rows.
current();
echo $row->bug_description;
]]>
Pourquoi ce mode déconnecté imposé ?
Un objet sérialisé est une chaîne de caractère, humainement visible. Il est
donc peut sécurisé d'y laisser un mot de passe vers un serveur de base de données.
Le lecteur d'un objet Rowset sérialisé ne devrait pas pouvoir accéder à la base de
données. De plus, une connexion à une base de données est un type non sérialisable
par PHP (ressource).
Il est bien entendu possible de reconnecter l'objet Rowset à la base de données,
et plus précisément à la Table dont il fut issu. Utilisez la méthode
setTable() et passez lui une instance héritant de
Zend_Db_Table_Abstract. Une fois reconnecté, l'objet Rowset
possède de nouveau un accès à la base de données, et n'est donc plus en mode lecture
seule.
Réactivation d'un Rowset
setTable($bugs);
$row = $rowset->current();
// Maintenant vous pouvez modifier les objets Row et les sauvegarder
$row->bug_status = 'FIXED';
$row->save();
]]>
Réactiver un Rowset avec setTable() réactive tous les Rows le
composant.
Étendre la classe Rowset
Vous pouvez utilisez votre propre classe étendant
Zend_Db_Table_Rowset_Abstract. Spécifiez votre classe dans la
propriété protégée $_rowsetClass de la classe de votre Table, ou dans le
tableau du constructeur de l'objet Table.
Spécifier sa propre classe de Rowset
'MyRowset'));
]]>
En temps normal, la classe standard Zend_Db_Rowset est suffisante. Cependant, il
peut être judicieux de rajouter de la logique dans son Rowset, pour une table précise.
Par exemple, une nouvelle méthode pourrait effectuer des calculs.
Exemple d'une classe Rowset personnalisée avec une nouvelle méthode
updated_at > $max_updated_at) {
$latestRow = $row;
}
}
return $latestRow;
}
}
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
protected $_rowsetClass = 'MyBugsRowset';
}
]]>