Zend_Db_Table_Rowset.xml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24508 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.db.table.rowset">
  5. <title>Zend_Db_Table_Rowset</title>
  6. <sect2 id="zend.db.table.rowset.introduction">
  7. <title>Introduction</title>
  8. <para>
  9. Lorsque vous effectuez une requête avec une classe de Table en utilisant
  10. <methodname>find()</methodname> ou <methodname>fetchAll()</methodname> , le résultat retourné est alors un objet
  11. de type <classname>Zend_Db_Table_Rowset_Abstract</classname>. Un Rowset est un conteneur
  12. d'objets descendants de <classname>Zend_Db_Table_Row_Abstract</classname>. Vous pouvez
  13. itérer à travers ce conteneur et accéder aux objet Row individuellement, en lecture ou
  14. écriture bien entendu.
  15. </para>
  16. </sect2>
  17. <sect2 id="zend.db.table.rowset.fetch">
  18. <title>Récupérer un Rowset</title>
  19. <para>
  20. <classname>Zend_Db_Table_Abstract</classname> possède des méthodes
  21. <methodname>find()</methodname> et <methodname>fetchAll()</methodname>, chacune retourne un objet de type
  22. <classname>Zend_Db_Table_Rowset_Abstract</classname>.
  23. </para>
  24. <example id="zend.db.table.rowset.fetch.example">
  25. <title>Exemple de récupération d'un rowset</title>
  26. <programlisting language="php"><![CDATA[
  27. $bugs = new Bugs();
  28. $rowset = $bugs->fetchAll("bug_status = 'NEW'");
  29. ]]></programlisting>
  30. </example>
  31. </sect2>
  32. <sect2 id="zend.db.table.rowset.rows">
  33. <title>Atteindre les Rows depuis un Rowset</title>
  34. <para>
  35. L'objet Rowset en lui-même n'est pas très intéressant au regard des objets Rows
  36. qu'il contient, qui eux, le sont bien plus.
  37. </para>
  38. <para>
  39. Un requête légitime peut retourner zéro enregistrement, donc zéro Rows. De ce
  40. fait, un objet Rowset peut contenir zéro objet Row. Comme
  41. <classname>Zend_Db_Table_Rowset_Abstract</classname> implémente l'interface
  42. <code>Countable</code>, vous pouvez utiliser la fonction <acronym>PHP</acronym> <methodname>count()</methodname>
  43. dessus, pour compter les Rows qu'il contient.
  44. </para>
  45. <example id="zend.db.table.rowset.rows.counting.example">
  46. <title>Compter les Rows dans un Rowset</title>
  47. <programlisting language="php"><![CDATA[
  48. $rowset = $bugs->fetchAll("bug_status = 'FIXED'");
  49. $rowCount = count($rowset);
  50. if ($rowCount > 0) {
  51. echo "$rowCount rows trouvés";
  52. } else {
  53. echo 'Pas de rows pour cette requête';
  54. }
  55. ]]></programlisting>
  56. </example>
  57. <example id="zend.db.table.rowset.rows.current.example">
  58. <title>Lecture d'un simple Row depuis un Rowset</title>
  59. <para>
  60. La façon la plus simple d'accéder à un Row depuis l'objet Rowset est
  61. d'utiliser la méthode <methodname>current()</methodname>. C'est tout à fait adapté lorsque le
  62. Rowset ne contient qu'un résultat (Row).
  63. </para>
  64. <programlisting language="php"><![CDATA[
  65. $bugs = new Bugs();
  66. $rowset = $bugs->fetchAll("bug_id = 1");
  67. $row = $rowset->current();
  68. ]]></programlisting>
  69. </example>
  70. <para>
  71. Si le Rowset ne contient aucun Row, <methodname>current()</methodname> retourne
  72. <constant>NULL</constant>.
  73. </para>
  74. <example id="zend.db.table.rowset.rows.iterate.example">
  75. <title>Itération à travers un Rowset</title>
  76. <para>
  77. Les objets descendants de <classname>Zend_Db_Table_Rowset_Abstract</classname>
  78. implémentent l'interface <code>Iterator</code>, ce qui veut dire qu'ils peuvent être
  79. utilisés dans la structure <acronym>PHP</acronym> <code>foreach</code>. Chaque valeur récupérée
  80. représente alors un objet de <classname>Zend_Db_Table_Row_Abstract</classname> qui
  81. correspond à un enregistrement dans la table.
  82. </para>
  83. <programlisting language="php"><![CDATA[
  84. $bugs = new Bugs();
  85. // récupère tous les enregistrements de la table
  86. $rowset = $bugs->fetchAll();
  87. foreach ($rowset as $row) {
  88. // affiche 'Zend_Db_Table_Row' par défaut
  89. echo get_class($row) . "\n";
  90. // lit une colonne dans le résultat Row
  91. $status = $row->bug_status;
  92. // modifie une colonne dans le résultat courant
  93. $row->assigned_to = 'mmouse';
  94. // Enregistre en base de données
  95. $row->save();
  96. }
  97. ]]></programlisting>
  98. </example>
  99. <example id="zend.db.table.rowset.rows.seek.example">
  100. <title>Déplacement vers une position précise dans le Rowset</title>
  101. <para>
  102. <code>SeekableIterator</code> vous permet de vus déplacer à une position
  103. précise dans l'itérateur. Utilisez pour ceci la méthode <methodname>seek()</methodname>. Elle
  104. prend en paramètre un entier représentant le numéro de la position désirée.
  105. N'oubliez pas que le premier enregistrement est stocké à la position zéro. Si vous
  106. spécifiez une position qui n'existe pas, une exception sera levée. Vous devriez
  107. utiliser <methodname>count()</methodname> pour vérifier le nombre d'enregistrements Rows
  108. présents.
  109. </para>
  110. <programlisting language="php"><![CDATA[
  111. $bugs = new Bugs();
  112. // récupère tous les enregistrements de la table
  113. $rowset = $bugs->fetchAll();
  114. // Déplace l'itérateur à l'enregistrement 8 (le neuvième donc) :
  115. $rowset->seek(8);
  116. // récupèration de cet enregistrement
  117. $row9 = $rowset->current();
  118. // et utilisation
  119. $row9->assigned_to = 'mmouse';
  120. $row9->save();
  121. ]]></programlisting>
  122. </example>
  123. <para>
  124. <methodname>getRow()</methodname> permet de retourner directement un enregistrement en
  125. fonction de sa position dans l'itérateur Rowset. Le premier paramètre est un entier
  126. représentant cette position. Le second paramètre est optionnel, et indique si oui ou non
  127. l'itérateur doit rester sur cette position, après avoir retourné le Row correspondant.
  128. Par défaut, il est à <constant>FALSE</constant>. Cette méthode retourne donc un objet
  129. <classname>Zend_Db_Table_Row</classname>. Si la position demandée n'existe pas, une
  130. exception est levée :
  131. </para>
  132. <programlisting language="php"><![CDATA[
  133. $bugs = new Bugs();
  134. // récupère tous les enregistrements de la table
  135. $rowset = $bugs->fetchAll();
  136. // récupère le neuvième enregistrement immédiatement
  137. $row9 = $rowset->getRow(8);
  138. // utilisation de l'enregistrement récupéré :
  139. $row9->assigned_to = 'mmouse';
  140. $row9->save();
  141. ]]></programlisting>
  142. <para>
  143. Dès que vous avez accès à un objet individuel Row, vous pouvez le piloter comme
  144. présenté dans la section <xref linkend="zend.db.table.row" />.
  145. </para>
  146. </sect2>
  147. <sect2 id="zend.db.table.rowset.to-array">
  148. <title>Récupérer un Rowset en tant que tableau (Array)</title>
  149. <para>
  150. Vous pouvez accéder à toutes les données d'un Rowset au moyen d'un tableau <acronym>PHP</acronym>
  151. avec la méthode <methodname>toArray()</methodname>. Ce tableau possède deux dimensions. Chaque
  152. entrée du tableau représente un tableau de l'objet Row. Les clés sont les noms des
  153. champs, et les valeurs leurs valeurs.
  154. </para>
  155. <example id="zend.db.table.rowset.to-array.example">
  156. <title>Utiliser toArray()</title>
  157. <programlisting language="php"><![CDATA[
  158. $bugs = new Bugs();
  159. $rowset = $bugs->fetchAll();
  160. $rowsetArray = $rowset->toArray();
  161. $rowCount = 1;
  162. foreach ($rowsetArray as $rowArray) {
  163. echo "row #$rowCount:\n";
  164. foreach ($rowArray as $column => $value) {
  165. echo "\t$column => $value\n";
  166. }
  167. ++$rowCount;
  168. echo "\n";
  169. }
  170. ]]></programlisting>
  171. </example>
  172. <para>
  173. Le tableau retourné par <methodname>toArray()</methodname> n'est pas une référence. Le
  174. modifier ne modifiera en aucun cas les données réelles dans la base de données.
  175. </para>
  176. </sect2>
  177. <sect2 id="zend.db.table.rowset.serialize">
  178. <title>Sérialisation et Désérialisation d'un Rowset</title>
  179. <para>
  180. Les objets de type <classname>Zend_Db_Table_Rowset_Abstract</classname> sont
  181. sérialisables. De la même manière que vous sérialisez un objet Row individuel, le Rowset
  182. est sérialisable et désérialisable.
  183. </para>
  184. <example id="zend.db.table.rowset.serialize.example.serialize">
  185. <title>Sérialiser d'un Rowset</title>
  186. <para>
  187. Utilisez simplement la fonction <acronym>PHP</acronym> <methodname>serialize()</methodname> pour créer une
  188. chaîne de caractères représentant votre objet Rowset.
  189. </para>
  190. <programlisting language="php"><![CDATA[
  191. $bugs = new Bugs();
  192. $rowset = $bugs->fetchAll();
  193. // Convertit l'objet en sa forme sérialisée
  194. $serializedRowset = serialize($rowset);
  195. // Maintenant vous pouvez écrire $serializedRowset
  196. // dans un fichier, etc.
  197. ]]></programlisting>
  198. </example>
  199. <example id="zend.db.table.rowset.serialize.example.unserialize">
  200. <title>Désérialisation d'un objet Rowset sérialisé</title>
  201. <para>Utilisez simplement la fonction <acronym>PHP</acronym> <methodname>unserialize()</methodname>.</para>
  202. <para>
  203. Notez que l'objet retourné fonctionne alors en mode
  204. <emphasis>déconnecté</emphasis>. Vous pouvez itérer à travers, et lire les objets
  205. Row qu'il contient, mais vous ne pouvez plus faire intervenir la base de données, ni
  206. changer de valeurs dans les Rows.
  207. </para>
  208. <programlisting language="php"><![CDATA[
  209. $rowsetDisconnected = unserialize($serializedRowset);
  210. // Maintenant vous pouvez utiliser l'objet, mais en lecture seule
  211. $row = $rowsetDisconnected->current();
  212. echo $row->bug_description;
  213. ]]></programlisting>
  214. </example>
  215. <note>
  216. <title>Pourquoi ce mode déconnecté imposé&#160;?</title>
  217. <para>
  218. Un objet sérialisé est une chaîne de caractère, humainement visible. Il est
  219. donc peut sécurisé d'y laisser un mot de passe vers un serveur de base de données.
  220. Le lecteur d'un objet Rowset sérialisé ne devrait pas pouvoir accéder à la base de
  221. données. De plus, une connexion à une base de données est un type non sérialisable
  222. par <acronym>PHP</acronym> (ressource).
  223. </para>
  224. </note>
  225. <para>
  226. Il est bien entendu possible de reconnecter l'objet Rowset à la base de données,
  227. et plus précisément à la Table dont il fut issu. Utilisez la méthode
  228. <methodname>setTable()</methodname> et passez lui une instance héritant de
  229. <classname>Zend_Db_Table_Abstract</classname>. Une fois reconnecté, l'objet Rowset
  230. possède de nouveau un accès à la base de données, et n'est donc plus en mode lecture
  231. seule.
  232. </para>
  233. <example id="zend.db.table.rowset.serialize.example.set-table">
  234. <title>Réactivation d'un Rowset</title>
  235. <programlisting language="php"><![CDATA[
  236. $rowset = unserialize($serializedRowset);
  237. $bugs = new Bugs();
  238. // Reconnecte le rowset à une table, et par
  239. // conséquent, à la connexion vers la base de données active
  240. $rowset->setTable($bugs);
  241. $row = $rowset->current();
  242. // Maintenant vous pouvez modifier les objets Row et les sauvegarder
  243. $row->bug_status = 'FIXED';
  244. $row->save();
  245. ]]></programlisting>
  246. </example>
  247. <para>
  248. Réactiver un Rowset avec <methodname>setTable()</methodname> réactive tous les Rows le
  249. composant.
  250. </para>
  251. </sect2>
  252. <sect2 id="zend.db.table.rowset.extending">
  253. <title>Étendre la classe Rowset</title>
  254. <para>
  255. Vous pouvez utilisez votre propre classe étendant
  256. <classname>Zend_Db_Table_Rowset_Abstract</classname>. Spécifiez votre classe dans la
  257. propriété protégée <varname>$_rowsetClass</varname> de la classe de votre Table, ou dans le
  258. tableau du constructeur de l'objet Table.
  259. </para>
  260. <example id="zend.db.table.rowset.extending.example">
  261. <title>Spécifier sa propre classe de Rowset</title>
  262. <programlisting language="php"><![CDATA[
  263. class MyRowset extends Zend_Db_Table_Rowset_Abstract
  264. {
  265. // ...personnalisations
  266. }
  267. // Spécifie la classe de Rowset utilisée pour toutes les
  268. // instance de la classe de Table
  269. class Products extends Zend_Db_Table_Abstract
  270. {
  271. protected $_name = 'products';
  272. protected $_rowsetClass = 'MyRowset';
  273. }
  274. // Ou pour une classe de table spécifique, via son constructeur
  275. $bugs = new Bugs(array('rowsetClass' => 'MyRowset'));
  276. ]]></programlisting>
  277. </example>
  278. <para>
  279. En temps normal, la classe standard Zend_Db_Rowset est suffisante. Cependant, il
  280. peut être judicieux de rajouter de la logique dans son Rowset, pour une table précise.
  281. Par exemple, une nouvelle méthode pourrait effectuer des calculs.
  282. </para>
  283. <example id="zend.db.table.rowset.extending.example-aggregate">
  284. <title>Exemple d'une classe Rowset personnalisée avec une nouvelle méthode</title>
  285. <programlisting language="php"><![CDATA[
  286. class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
  287. {
  288. /**
  289. * Trouve les Rows dans le Rowset courant avec la plus grande
  290. * valeur pour la colonne 'updated_at'.
  291. */
  292. public function getLatestUpdatedRow()
  293. {
  294. $max_updated_at = 0;
  295. $latestRow = null;
  296. foreach ($this as $row) {
  297. if ($row->updated_at > $max_updated_at) {
  298. $latestRow = $row;
  299. }
  300. }
  301. return $latestRow;
  302. }
  303. }
  304. class Bugs extends Zend_Db_Table_Abstract
  305. {
  306. protected $_name = 'bugs';
  307. protected $_rowsetClass = 'MyBugsRowset';
  308. }
  309. ]]></programlisting>
  310. </example>
  311. </sect2>
  312. </sect1>