Zend_Db_Table_Rowset.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. <sect1 id="zend.db.table.rowset">
  2. <title>Zend_Db_Table_Rowset</title>
  3. <sect2 id="zend.db.table.rowset.introduction">
  4. <title>Введение</title>
  5. <para>
  6. Когда вы производите запрос через класс таблицы, используя методы
  7. <code>find()</code> или <code>fetchAll()</code>, результат
  8. возвращается в объекте типа
  9. <code>Zend_Db_Table_Rowset_Abstract</code>. Набор
  10. строк (rowset) содержит коллекцию объектов, наследующих от
  11. <code>Zend_Db_Table_Row_Abstract</code>. Вы можете
  12. производить итерацию по набору строк и работать с отдельными
  13. объектами строк, считывая или изменяя данные в строках.
  14. </para>
  15. </sect2>
  16. <sect2 id="zend.db.table.rowset.fetch">
  17. <title>Получение набора строк</title>
  18. <para>
  19. <code>Zend_Db_Table_Abstract</code> предоставляет методы
  20. <code>find()</code> и <code>fetchAll()</code>, оба они возвращают
  21. объект типа <code>Zend_Db_Table_Rowset_Abstract</code>.
  22. </para>
  23. <example id="zend.db.table.rowset.fetch.example">
  24. <title>Пример извлечения набора строк</title>
  25. <programlisting language="php"><![CDATA[
  26. $bugs = new Bugs();
  27. $rowset = $bugs->fetchAll("bug_status = 'NEW'");
  28. ]]>
  29. </programlisting>
  30. </example>
  31. </sect2>
  32. <sect2 id="zend.db.table.rowset.rows">
  33. <title>Получение строк из набора</title>
  34. <para>
  35. Обычно сам по себе набор строк представляет меньший интерес, чем
  36. строки, содержащиеся в нем. Этот раздел показывает, как получать
  37. строки из набора строк.
  38. </para>
  39. <para>
  40. Правильно составленный запрос возвращает нулевое количество строк,
  41. если в БД нет строк, соответствующих условиям запроса. Поэтому
  42. объект набора строк может содержать нулевое количество объектов
  43. строк. Поскольку <code>Zend_Db_Table_Rowset_Abstract</code>
  44. реализует инерфейс <code>Countable</code>, то вы можете использовать
  45. <code>count()</code> для определения количества строк в наборе
  46. строк.
  47. </para>
  48. <example id="zend.db.table.rowset.rows.example.counting">
  49. <title>Подсчет количества строк в наборе строк</title>
  50. <programlisting language="php"><![CDATA[
  51. $rowset = $bugs->fetchAll("bug_status = 'FIXED'");
  52. $rowCount = count($rowset);
  53. if ($rowCount > 0) {
  54. echo "found $rowCount rows";
  55. } else {
  56. echo 'no rows matched the query';
  57. }
  58. ]]>
  59. </programlisting>
  60. </example>
  61. <example id="zend.db.table.rowset.rows.example.current">
  62. <title>Чтение одной строки из набора строк</title>
  63. <para>
  64. Наиболее простой способ получения доступа к строке из набора
  65. состоит в использовании метода <code>current()</code>. Этот
  66. способ особенно подходит для тех случаев, когда набор строк
  67. содержит только одну строку.
  68. </para>
  69. <programlisting language="php"><![CDATA[
  70. $bugs = new Bugs();
  71. $rowset = $bugs->fetchAll("bug_id = 1");
  72. $row = $rowset->current();
  73. ]]>
  74. </programlisting>
  75. </example>
  76. <para>
  77. Если набор строк содержит нулевое количество строк, то
  78. <code>current()</code> вернет значение <constant>NULL</constant>.
  79. </para>
  80. <example id="zend.db.table.rowset.iterate.example">
  81. <title>>Итерация по набору строк</title>
  82. <para>
  83. Объекты, наследующие от
  84. <code>Zend_Db_Table_Rowset_Abstract</code>, реализуют интерфейс
  85. <code>Iterator</code>. Это значит, что можно производить
  86. циклический обход объектов, используя конструкцию
  87. <code>foreach()</code>. Каждое значение, получаемое таким
  88. образом, является объектом типа
  89. <code>Zend_Db_Table_Row_Abstract</code>, который соответствует
  90. одной записи в таблице.
  91. </para>
  92. <programlisting language="php"><![CDATA[
  93. $bugs = new Bugs();
  94. // извлечение всех записей из таблицы
  95. $rowset = $bugs->fetchAll();
  96. foreach ($rowset as $row) {
  97. // выводит 'Zend_Db_Table_Row' или подобное
  98. echo get_class($row) . "\n";
  99. // чтение столбца в строке
  100. $status = $row->bug_status;
  101. // изменение столбца в текущей строке
  102. $row->assigned_to = 'mmouse';
  103. // сохранение изменений в БД
  104. $row->save();
  105. }
  106. ]]>
  107. </programlisting>
  108. </example>
  109. <para>
  110. <code>getRow()</code> позволяет извлекать строку из
  111. набора строк, используя номер ее позиции, при этом не забывайте,
  112. что отсчет позиции начинается с нуля. Первый параметр метода
  113. <code>getRow()</code> должен быть целочисленным и используется
  114. для передачи позиции строки. Второй
  115. необязательный параметр должен иметь булев тип, при передаче
  116. значения true итератор перемещается в данную позицию
  117. (по умолчанию используется значение false). По умолчанию
  118. этот метод возвращает объект Zend_Db_Table_Row. Если запрошенная
  119. позиция не существует, то бросается исключение. Ниже приведен
  120. пример:
  121. </para>
  122. <programlisting language="php"><![CDATA[
  123. $bugs = new Bugs();
  124. // извлечение всех строк из таблицы
  125. $rowset = $bugs->fetchAll();
  126. // извлечение девятой строки:
  127. $row9->getRow(8);
  128. // и ее применение:
  129. $row9->assigned_to = 'mmouse';
  130. $row9->save();
  131. ]]>
  132. </programlisting>
  133. <para>
  134. После того, как получен отдельный объект строки, вы можете
  135. работать с ним, используя методы, описанные в
  136. <xref linkend="zend.db.table.row" />
  137. </para>
  138. </sect2>
  139. <sect2 id="zend.db.table.rowset.to-array">
  140. <title>Получение набора строк в виде массива</title>
  141. <para>
  142. Вы можете работать с данными в наборе строк как с массивом,
  143. используя метод <code>toArray()</code> объекта набора строк. Он
  144. возвращает массив, содержащий по одной записи на строку. Каждая
  145. запись является ассоциативным массивом, в котором ключи
  146. соответствуют именам столбцов, а элементы - значениям этих столбцов.
  147. </para>
  148. <example id="zend.db.table.rowset.to-array.example">
  149. <title>Использование toArray()</title>
  150. <programlisting language="php"><![CDATA[
  151. $bugs = new Bugs();
  152. $rowset = $bugs->fetchAll();
  153. $rowsetArray = $rowset->toArray();
  154. $rowCount = 1;
  155. foreach ($rowsetArray as $rowArray) {
  156. echo "row #$rowCount:\n";
  157. foreach ($rowArray as $column => $value) {
  158. echo "\t$column => $value\n";
  159. }
  160. ++$rowCount;
  161. echo "\n";
  162. }
  163. ]]>
  164. </programlisting>
  165. </example>
  166. <para>
  167. Массив, возвращаемый методом <code>toArray()</code> не может
  168. использоваться для обновления данных в БД. Вы можете изменять
  169. значения в этом массиве так же, как и в любом другом массиве, но
  170. эти изменения не сохраняются в БД.
  171. </para>
  172. </sect2>
  173. <sect2 id="zend.db.table.rowset.serialize">
  174. <title>Сериализация и десериализация наборов строк</title>
  175. <para>
  176. Объекты типа <code>Zend_Db_Table_Rowset_Abstract</code> доступны для
  177. сериализации. Сериализация производится так же, как и для отдельных
  178. объектов строк - вы можете сериализовать объект набора строк и
  179. восстановить его позднее.
  180. </para>
  181. <example id="zend.db.table.rowset.serialize.example.serialize">
  182. <title>Сериализация набора строк</title>
  183. <para>
  184. Используйте PHP-функцию <code>serialize()</code> для
  185. получения строки, содержащей представление объекта набора строк
  186. в виде последовательности байт.
  187. </para>
  188. <programlisting language="php"><![CDATA[
  189. $bugs = new Bugs();
  190. $rowset = $bugs->fetchAll();
  191. // Преобразование объекта в сериализованную форму
  192. $serializedRowset = serialize($rowset);
  193. // Теперь вы можете записать $serializedRowset в файл и т.п.
  194. ]]>
  195. </programlisting>
  196. </example>
  197. <example id="zend.db.table.rowset.serialize.example.unserialize">
  198. <title>Десериализация набора строк</title>
  199. <para>
  200. Используйте функцию <code>unserialize()</code> для
  201. восстановления из строки, содержащей представление объекта в
  202. виде последовательности байт. Эта функция возвращает исходный
  203. объект.
  204. </para>
  205. <para>
  206. Внимание: объект набора строк возвращается <emphasis>без
  207. соединения с БД</emphasis>. Вы можете производить циклический
  208. обход набора строк, читать объекты строк и их свойства, но не
  209. изменять значения в строках или выполнять другие методы,
  210. требующие соединения с БД (например, запросы к связанным
  211. таблицам).
  212. </para>
  213. <programlisting language="php"><![CDATA[
  214. $rowsetDisconnected = unserialize($serializedRowset);
  215. // Теперь вы можете использовать свойства и методы объекта, но только для чтения
  216. $row = $rowsetDisconnected->current();
  217. echo $row->bug_description;
  218. ]]>
  219. </programlisting>
  220. </example>
  221. <note>
  222. <title>Почему объекты наборов строк десериализируются без соединения с БД?</title>
  223. <para>
  224. Сериализованный объект является строкой, которая доступна
  225. для чтения всем, кто ею обладает.
  226. Это создает угрозу безопасности, которая состоит в
  227. том, что в сериализованной строке сохраняются такие
  228. параметры, как логин и пароль для соединения с БД, в
  229. незашифрованном виде.
  230. Для вас может быть нежелательным сохранять такие данные в
  231. незащищенном текстовом файле, отправлять его через e-mail
  232. или любой другой носитель, который может быть прочитан
  233. потенциальным атакующим.
  234. Тот, кто прочитает сериализованный объект, не должен иметь
  235. возможности использовать его для получения
  236. несанкционированного доступа к БД.
  237. </para>
  238. </note>
  239. <para>
  240. Вы можете восстановить соединение для набора строк, используя
  241. метод <code>setTable()</code>. Аргументом этого метода является
  242. объект типа <code>Zend_Db_Table_Abstract</code>, который создается
  243. вами. Создание объекта таблицы требует действующего соединения с БД,
  244. поэтому при переустановке таблицы объект набора строк получает
  245. доступ к БД. После этого вы сможете изменять значения объектов
  246. строк, содержащихся в объекте набора строк и сохранять изменения
  247. в БД.
  248. </para>
  249. <example id="zend.db.table.rowset.serialize.example.set-table">
  250. <title>Пример восстановления соединения для набора строк</title>
  251. <programlisting language="php"><![CDATA[
  252. $rowset = unserialize($serializedRowset);
  253. $bugs = new Bugs();
  254. // Переустановка таблицы для набора строк,
  255. // заодно восстанавливается соединение с БД
  256. $rowset->setTable($bugs);
  257. $row = $rowset->current();
  258. // Теперь можно производить изменения в строке и сохранять их
  259. $row->bug_status = 'FIXED';
  260. $row->save();
  261. ]]>
  262. </programlisting>
  263. </example>
  264. <para>
  265. Восстановление соединения для набора строк через метод
  266. <code>setTable()</code> делает то же самое для всех объектов
  267. строк, содержащихся в этом наборе строк.
  268. </para>
  269. </sect2>
  270. <sect2 id="zend.db.table.rowset.extending">
  271. <title>Расширение класса набора строк</title>
  272. <para>
  273. Вы можете использовать альтернативный класс для наборов
  274. строк путем расширения класса Zend_Db_Table_Rowset_Abstract.
  275. Указывайте новый класс набора строк через имя в защищенном свойстве
  276. <varname>$_rowsetClass</varname> класса таблицы или в массиве,
  277. передаваемом в качестве аргумента конструктору объекта таблицы.
  278. </para>
  279. <example id="zend.db.table.rowset.extending.example">
  280. <title>Указание своего класса набора строк</title>
  281. <programlisting language="php"><![CDATA[
  282. class MyRowset extends Zend_Db_Table_Rowset_Abstract
  283. {
  284. // ...кастомизация
  285. }
  286. // Укажите свой класс набора строк в качестве используемого по умолчанию
  287. // во всех экземплярах класса таблицы
  288. class Products extends Zend_Db_Table_Abstract
  289. {
  290. protected $_name = 'products';
  291. protected $_rowsetClass = 'MyRowset';
  292. }
  293. // Или укажите свой класс набора строк для использования
  294. // в конкретном экземпляре класса таблицы
  295. ]]>
  296. </programlisting>
  297. </example>
  298. <para>
  299. Стандартный класс Zend_Db_Rowset подходит для большинства случаев
  300. использования. Тем не менее, может потребоваться добавить свою
  301. логику в набор строк, специфический для данной таблицы.
  302. Например, новый метод может вычислять агрегированное значение для
  303. всех строк в наборе.
  304. </para>
  305. <example id="zend.db.table.rowset.extending.example-aggregate">
  306. <title>Пример класса набора строк с новым методом</title>
  307. <programlisting language="php"><![CDATA[
  308. class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
  309. {
  310. /**
  311. * Находит в текущем наборе строку с наибольшим
  312. * значением в столбце 'updated_at'
  313. */
  314. public function getLatestUpdatedRow()
  315. {
  316. $max_updated_at = 0;
  317. $latestRow = null;
  318. foreach ($this as $row) {
  319. if ($row->updated_at > $max_updated_at) {
  320. $latestRow = $row;
  321. }
  322. }
  323. return $latestRow;
  324. }
  325. }
  326. class Bugs extends Zend_Db_Table_Abstract
  327. {
  328. protected $_name = 'bugs';
  329. protected $_rowsetClass = 'MyBugsRowset';
  330. }
  331. ]]>
  332. </programlisting>
  333. </example>
  334. </sect2>
  335. </sect1>
  336. <!--
  337. vim:se ts=4 sw=4 et:
  338. -->