| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- <!-- EN-Revision: 13846 -->
- <sect1 id="zend.db.table.rowset">
- <title>Zend_Db_Table_Rowset</title>
- <sect2 id="zend.db.table.rowset.introduction">
- <title>Introduction</title>
- <para>Lorsque vous effectuez une requête avec une classe de Table en utilisant <code>find()</code> ou
- <code>fetchAll()</code> , le résultat retourné est alors un objet de type
- <classname>Zend_Db_Table_Rowset_Abstract</classname>. Un Rowset est un conteneur d'objets descendants de
- <classname>Zend_Db_Table_Row_Abstract</classname>. Vous pouvez itérer à travers ce conteneur et accéder aux objet Row
- individuellement, en lecture ou écriture bien entendu.</para>
- </sect2>
- <sect2 id="zend.db.table.rowset.fetch">
- <title>Récupérer un Rowset</title>
- <para><classname>Zend_Db_Table_Abstract</classname> possède des méthodes <code>find()</code> et <code>fetchAll()</code>,
- chacune retourne un objet de type <classname>Zend_Db_Table_Rowset_Abstract</classname>.</para>
- <example id="zend.db.table.rowset.fetch.example">
- <title>Exemple de récupération d'un rowset</title>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- $rowset = $bugs->fetchAll("bug_status = 'NEW'");
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.table.rowset.rows">
- <title>Atteindre les Rows depuis un Rowset</title>
- <para>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.</para>
- <para>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 <classname>Zend_Db_Table_Rowset_Abstract</classname> implémente l'interface
- <code>Countable</code>, vous pouvez utiliser la fonction PHP <code>count()</code> dessus, pour compter les Rows
- qu'il contient.</para>
- <example id="zend.db.table.rowset.rows.counting.example">
- <title>Compter les Rows dans un Rowset</title>
- <programlisting role="php"><![CDATA[
- $rowset = $bugs->fetchAll("bug_status = 'FIXED'");
- $rowCount = count($rowset);
- if ($rowCount > 0) {
- echo "$rowCount rows trouvés";
- } else {
- echo 'Pas de rows pour cette requête';
- }
- ]]></programlisting>
- </example>
- <example id="zend.db.table.rowset.rows.current.example">
- <title>Lecture d'un simple Row depuis un Rowset</title>
- <para>La façon la plus simple d'accéder à un Row depuis l'objet Rowset est d'utiliser la méthode
- <code>current()</code>. C'est tout à fait adapté lorsque le Rowset ne contient qu'un résultat (Row).</para>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- $rowset = $bugs->fetchAll("bug_id = 1");
- $row = $rowset->current();
- ]]></programlisting>
- </example>
- <para>Si le Rowset ne contient aucun Row, <code>current()</code> retourne <code>null</code>.</para>
- <example id="zend.db.table.rowset.rows.iterate.example">
- <title>Itération à travers un Rowset</title>
- <para>Les objets descendants de <classname>Zend_Db_Table_Rowset_Abstract</classname> implémentent l'interface
- <code>Iterator</code>, ce qui veut dire qu'ils peuvent être utilisés dans la structure PHP
- <code>foreach</code>. Chaque valeur récupérée représente alors un objet de
- <classname>Zend_Db_Table_Row_Abstract</classname> qui correspond à un enregistrement dans la table.</para>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- // récupère tous les enregistrements de la table
- $rowset = $bugs->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();
- }
- ]]></programlisting>
- </example>
- <example id="zend.db.table.rowset.rows.seek.example">
- <title>Déplacement vers une position précise dans le Rowset</title>
- <para><code>SeekableIterator</code> vous permet de vus déplacer à une position précise dans l'itérateur.
- Utilisez pour ceci la méthode <code>seek()</code>. 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
- <code>count()</code> pour vérifier le nombre d'enregistrements Rows présents.</para>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- // récupère tous les enregistrements de la table
- $rowset = $bugs->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();
- ]]></programlisting>
- </example>
- <para><code>getRow()</code> 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 à <code>false</code>. Cette méthode retourne donc un objet
- <classname>Zend_Db_Table_Row</classname>. Si la position demandée n'existe pas, une exception est levée :</para>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- // récupère tous les enregistrements de la table
- $rowset = $bugs->fetchAll();
- // récupère le neuvième enregistrement immédiatement
- $row9->getRow(8);
- // utilisation de l'enregistrement récupéré :
- $row9->assigned_to = 'mmouse';
- $row9->save();
- ]]></programlisting>
- <para>Dès que vous avez accès à un objet individuel Row, vous pouvez le piloter comme présenté dans la section
- <xref linkend="zend.db.table.row" />.</para>
- </sect2>
- <sect2 id="zend.db.table.rowset.to-array">
- <title>Récupérer un Rowset en tant que tableau (Array)</title>
- <para>Vous pouvez accéder à toutes les données d'un Rowset au moyen d'un tableau PHP avec la méthode
- <code>toArray()</code>. 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.</para>
- <example id="zend.db.table.rowset.to-array.example">
- <title>Utiliser <code>toArray()</code></title>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- $rowset = $bugs->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";
- }
- ]]></programlisting>
- </example>
- <para>Le tableau retourné par <code>toArray()</code> 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.</para>
- </sect2>
- <sect2 id="zend.db.table.rowset.serialize">
- <title>Sérialisation et Désérialisation d'un Rowset</title>
- <para>Les objets de type <classname>Zend_Db_Table_Rowset_Abstract</classname> 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.</para>
- <example id="zend.db.table.rowset.serialize.example.serialize">
- <title>Sérialiser d'un Rowset</title>
- <para>Utilisez simplement la fonction PHP <code>serialize()</code> pour créer une chaîne de caractères
- représentant votre objet Rowset.</para>
- <programlisting role="php"><![CDATA[
- $bugs = new Bugs();
- $rowset = $bugs->fetchAll();
- // Convertit l'objet en sa forme sérialisée
- $serializedRowset = serialize($rowset);
- // Maintenant vous pouvez écrire $serializedRowset
- // dans un fichier, etc.
- ]]></programlisting>
- </example>
- <example id="zend.db.table.rowset.serialize.example.unserialize">
- <title>Désérialisation d'un objet Rowset sérialisé</title>
- <para>Utilisez simplement la fonction PHP <code>unserialize()</code>.</para>
- <para>Notez que l'objet retourné fonctionne alors en mode <emphasis>déconnecté</emphasis>. 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.</para>
- <programlisting role="php"><![CDATA[
- $rowsetDisconnected = unserialize($serializedRowset);
- // Maintenant vous pouvez utiliser l'objet, mais en lecture seule
- $row = $rowsetDisconnected->current();
- echo $row->bug_description;
- ]]></programlisting>
- </example>
- <note>
- <title>Pourquoi ce mode déconnecté imposé ?</title>
- <para>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).</para>
- </note>
- <para>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 <code>setTable()</code> et passez lui une instance héritant de
- <classname>Zend_Db_Table_Abstract</classname>. 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.</para>
- <example id="zend.db.table.rowset.serialize.example.set-table">
- <title>Réactivation d'un Rowset</title>
- <programlisting role="php"><![CDATA[
- $rowset = unserialize($serializedRowset);
- $bugs = new Bugs();
- // Reconnecte le rowset à une table, et par
- // conséquent, à la connexion vers la base de données active
- $rowset->setTable($bugs);
- $row = $rowset->current();
- // Maintenant vous pouvez modifier les objets Row et les sauvegarder
- $row->bug_status = 'FIXED';
- $row->save();
- ]]></programlisting>
- </example>
- <para>Réactiver un Rowset avec <code>setTable()</code> réactive tous les Rows le composant.</para>
- </sect2>
- <sect2 id="zend.db.table.rowset.extending">
- <title>Étendre la classe Rowset</title>
- <para>Vous pouvez utilisez votre propre classe étendant <classname>Zend_Db_Table_Rowset_Abstract</classname>. Spécifiez
- votre classe dans la propriété protégée <code>$_rowsetClass</code> de la classe de votre Table, ou dans le
- tableau du constructeur de l'objet Table.</para>
- <example id="zend.db.table.rowset.extending.example">
- <title>Spécifier sa propre classe de Rowset</title>
- <programlisting role="php"><![CDATA[
- class MyRowset extends Zend_Db_Table_Rowset_Abstract
- {
- // ...personnalisations
- }
- // Spécifie la classe de Rowset utilisée pour toutes les
- // instance de la classe de Table
- class Products extends Zend_Db_Table_Abstract
- {
- protected $_name = 'products';
- protected $_rowsetClass = 'MyRowset';
- }
- // Ou pour une classe de table spécifique, via son constructeur
- $bugs = new Bugs(array('rowsetClass' => 'MyRowset'));
- ]]></programlisting>
- </example>
- <para>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.</para>
- <example id="zend.db.table.rowset.extending.example-aggregate">
- <title>Exemple d'une classe Rowset personnalisée avec une nouvelle méthode</title>
- <programlisting role="php"><![CDATA[
- class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
- {
- /**
- * Trouve les Rows dans le Rowset courant avec la plus grande
- * valeur pour la colonne 'updated_at'.
- */
- public function getLatestUpdatedRow()
- {
- $max_updated_at = 0;
- $latestRow = null;
- foreach ($this as $row) {
- if ($row->updated_at > $max_updated_at) {
- $latestRow = $row;
- }
- }
- return $latestRow;
- }
- }
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- protected $_rowsetClass = 'MyBugsRowset';
- }
- ]]></programlisting>
- </example>
- </sect2>
- </sect1>
|