| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24508 -->
- <!-- Reviewed: no -->
- <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
- <methodname>find()</methodname> ou <methodname>fetchAll()</methodname> , 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
- <methodname>find()</methodname> et <methodname>fetchAll()</methodname>, 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 language="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 <acronym>PHP</acronym> <methodname>count()</methodname>
- 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 language="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 <methodname>current()</methodname>. C'est tout à fait adapté lorsque le
- Rowset ne contient qu'un résultat (Row).
- </para>
- <programlisting language="php"><![CDATA[
- $bugs = new Bugs();
- $rowset = $bugs->fetchAll("bug_id = 1");
- $row = $rowset->current();
- ]]></programlisting>
- </example>
- <para>
- Si le Rowset ne contient aucun Row, <methodname>current()</methodname> retourne
- <constant>NULL</constant>.
- </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 <acronym>PHP</acronym> <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 language="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 <methodname>seek()</methodname>. 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 <methodname>count()</methodname> pour vérifier le nombre d'enregistrements Rows
- présents.
- </para>
- <programlisting language="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>
- <methodname>getRow()</methodname> 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 à <constant>FALSE</constant>. 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 language="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 = $rowset->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 <acronym>PHP</acronym>
- avec la méthode <methodname>toArray()</methodname>. 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 toArray()</title>
- <programlisting language="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 <methodname>toArray()</methodname> 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 <acronym>PHP</acronym> <methodname>serialize()</methodname> pour créer une
- chaîne de caractères représentant votre objet Rowset.
- </para>
- <programlisting language="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 <acronym>PHP</acronym> <methodname>unserialize()</methodname>.</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 language="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 <acronym>PHP</acronym> (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
- <methodname>setTable()</methodname> 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 language="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 <methodname>setTable()</methodname> 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 <varname>$_rowsetClass</varname> 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 language="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 language="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>
|