[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_Db_Table_Rowset.xml
blob851157819b7c6b433ae26bec173c2bb382a480a1
1 <sect1 id="zend.db.table.rowset">
3     <title>Zend_Db_Table_Rowset</title>
5     <sect2 id="zend.db.table.rowset.introduction">
7         <title>Введение</title>
9         <para>
10             Когда вы производите запрос через класс таблицы, используя методы
11             <code>find()</code> или <code>fetchAll()</code>, результат
12             возвращается в объекте типа
13             <code>Zend_Db_Table_Rowset_Abstract</code>. Набор
14             строк (rowset) содержит коллекцию объектов, наследующих от
15             <code>Zend_Db_Table_Row_Abstract</code>. Вы можете
16             производить итерацию по набору строк и работать с отдельными
17             объектами строк, считывая или изменяя данные в строках.
18         </para>
20     </sect2>
22     <sect2 id="zend.db.table.rowset.fetch">
24         <title>Получение набора строк</title>
26         <para>
27             <code>Zend_Db_Table_Abstract</code> предоставляет методы
28             <code>find()</code> и <code>fetchAll()</code>, оба они возвращают
29             объект типа <code>Zend_Db_Table_Rowset_Abstract</code>.
30         </para>
32         <example id="zend.db.table.rowset.fetch.example">
34             <title>Пример извлечения набора строк</title>
36             <programlisting language="php"><![CDATA[
37 $bugs   = new Bugs();
38 $rowset = $bugs->fetchAll("bug_status = 'NEW'");
39 ]]>
40             </programlisting>
42         </example>
44     </sect2>
46     <sect2 id="zend.db.table.rowset.rows">
48         <title>Получение строк из набора</title>
50         <para>
51             Обычно сам по себе набор строк представляет меньший интерес, чем
52             строки, содержащиеся в нем. Этот раздел показывает, как получать
53             строки из набора строк.
54         </para>
56         <para>
57             Правильно составленный запрос возвращает нулевое количество строк,
58             если в БД нет строк, соответствующих условиям запроса. Поэтому
59             объект набора строк может содержать нулевое количество объектов
60             строк. Поскольку <code>Zend_Db_Table_Rowset_Abstract</code>
61             реализует инерфейс <code>Countable</code>, то вы можете использовать
62             <code>count()</code> для определения количества строк в наборе
63             строк.
64         </para>
66         <example id="zend.db.table.rowset.rows.example.counting">
68             <title>Подсчет количества строк в наборе строк</title>
70             <programlisting language="php"><![CDATA[
71 $rowset   = $bugs->fetchAll("bug_status = 'FIXED'");
73 $rowCount = count($rowset);
75 if ($rowCount > 0) {
76     echo "found $rowCount rows";
77 } else {
78     echo 'no rows matched the query';
80 ]]>
81             </programlisting>
83         </example>
85         <example id="zend.db.table.rowset.rows.example.current">
87             <title>Чтение одной строки из набора строк</title>
89             <para>
90                 Наиболее простой способ получения доступа к строке из набора
91                 состоит в использовании метода <code>current()</code>. Этот
92                 способ особенно подходит для тех случаев, когда набор строк
93                 содержит только одну строку.
94             </para>
96             <programlisting language="php"><![CDATA[
97 $bugs   = new Bugs();
98 $rowset = $bugs->fetchAll("bug_id = 1");
99 $row    = $rowset->current();
101             </programlisting>
103         </example>
105         <para>
106             Если набор строк содержит нулевое количество строк, то
107             <code>current()</code> вернет значение <constant>NULL</constant>.
108         </para>
110         <example id="zend.db.table.rowset.iterate.example">
112             <title>>Итерация по набору строк</title>
114             <para>
115                 Объекты, наследующие от
116                 <code>Zend_Db_Table_Rowset_Abstract</code>, реализуют интерфейс
117                 <code>Iterator</code>. Это значит, что можно производить
118                 циклический обход объектов, используя конструкцию
119                 <code>foreach()</code>. Каждое значение, получаемое таким
120                 образом, является объектом типа
121                 <code>Zend_Db_Table_Row_Abstract</code>, который соответствует
122                 одной записи в таблице.
123             </para>
125             <programlisting language="php"><![CDATA[
126 $bugs = new Bugs();
128 // извлечение всех записей из таблицы
129 $rowset = $bugs->fetchAll();
131 foreach ($rowset as $row) {
133     // выводит 'Zend_Db_Table_Row' или подобное
134     echo get_class($row) . "\n";
136     // чтение столбца в строке
137     $status = $row->bug_status;
139     // изменение столбца в текущей строке
140     $row->assigned_to = 'mmouse';
142     // сохранение изменений в БД
143     $row->save();
146             </programlisting>
148         </example>
150             <para>
151                 <code>getRow()</code> позволяет извлекать строку из
152                 набора строк, используя номер ее позиции, при этом не забывайте,
153                 что отсчет позиции начинается с нуля. Первый параметр метода
154                 <code>getRow()</code> должен быть целочисленным и используется
155                 для передачи позиции строки. Второй
156                 необязательный параметр должен иметь булев тип, при передаче
157                 значения true итератор перемещается в данную позицию
158                 (по умолчанию используется значение false). По умолчанию
159                 этот метод возвращает объект Zend_Db_Table_Row. Если запрошенная
160                 позиция не существует, то бросается исключение. Ниже приведен
161                 пример:
162             </para>
164             <programlisting language="php"><![CDATA[
165 $bugs = new Bugs();
167 // извлечение всех строк из таблицы
168 $rowset = $bugs->fetchAll();
170 // извлечение девятой строки:
171 $row9->getRow(8);
173 // и ее применение:
174 $row9->assigned_to = 'mmouse';
175 $row9->save();
177             </programlisting>
179         <para>
180             После того, как получен отдельный объект строки, вы можете
181             работать с ним, используя методы, описанные в
182             <xref linkend="zend.db.table.row" />
183         </para>
185     </sect2>
187     <sect2 id="zend.db.table.rowset.to-array">
189         <title>Получение набора строк в виде массива</title>
191         <para>
192             Вы можете работать с данными в наборе строк как с массивом,
193             используя метод <code>toArray()</code> объекта набора строк. Он
194             возвращает массив, содержащий по одной записи на строку. Каждая
195             запись является ассоциативным массивом, в котором ключи
196             соответствуют именам столбцов, а элементы - значениям этих столбцов.
197         </para>
199         <example id="zend.db.table.rowset.to-array.example">
201             <title>Использование toArray()</title>
203             <programlisting language="php"><![CDATA[
204 $bugs   = new Bugs();
205 $rowset = $bugs->fetchAll();
207 $rowsetArray = $rowset->toArray();
209 $rowCount = 1;
210 foreach ($rowsetArray as $rowArray) {
211     echo "row #$rowCount:\n";
212     foreach ($rowArray as $column => $value) {
213         echo "\t$column => $value\n";
214     }
215     ++$rowCount;
216     echo "\n";
219             </programlisting>
220         </example>
222         <para>
223             Массив, возвращаемый методом <code>toArray()</code> не может
224             использоваться для обновления данных в БД. Вы можете изменять
225             значения в этом массиве так же, как и в любом другом массиве, но
226             эти изменения не сохраняются в БД.
227         </para>
229     </sect2>
231     <sect2 id="zend.db.table.rowset.serialize">
233         <title>Сериализация и десериализация наборов строк</title>
235         <para>
236             Объекты типа <code>Zend_Db_Table_Rowset_Abstract</code> доступны для
237             сериализации. Сериализация производится так же, как и для отдельных
238             объектов строк - вы можете сериализовать объект набора строк и
239             восстановить его позднее.
240         </para>
242         <example id="zend.db.table.rowset.serialize.example.serialize">
244             <title>Сериализация набора строк</title>
246             <para>
247                 Используйте PHP-функцию <code>serialize()</code> для
248                 получения строки, содержащей представление объекта набора строк
249                 в виде последовательности байт.
250             </para>
252             <programlisting language="php"><![CDATA[
253 $bugs   = new Bugs();
254 $rowset = $bugs->fetchAll();
256 // Преобразование объекта в сериализованную форму
257 $serializedRowset = serialize($rowset);
259 // Теперь вы можете записать $serializedRowset в файл и т.п.
261             </programlisting>
263         </example>
265         <example id="zend.db.table.rowset.serialize.example.unserialize">
267             <title>Десериализация набора строк</title>
269             <para>
270                 Используйте функцию <code>unserialize()</code> для
271                 восстановления из строки, содержащей представление объекта в
272                 виде последовательности байт. Эта функция возвращает исходный
273                 объект.
274             </para>
276             <para>
277                 Внимание: объект набора строк возвращается <emphasis>без
278                 соединения с БД</emphasis>. Вы можете производить циклический
279                 обход набора строк, читать объекты строк и их свойства, но не
280                 изменять значения в строках или выполнять другие методы,
281                 требующие соединения с БД (например, запросы к связанным
282                 таблицам).
283             </para>
285             <programlisting language="php"><![CDATA[
286 $rowsetDisconnected = unserialize($serializedRowset);
288 // Теперь вы можете использовать свойства и методы объекта, но только для чтения
289 $row = $rowsetDisconnected->current();
290 echo $row->bug_description;
292             </programlisting>
294         </example>
296         <note>
297             <title>Почему объекты наборов строк десериализируются без соединения с БД?</title>
298             <para>
299                 Сериализованный объект является строкой, которая доступна
300                 для чтения всем, кто ею обладает.
301                 Это создает угрозу безопасности, которая состоит в
302                 том, что в сериализованной строке сохраняются такие
303                 параметры, как логин и пароль для соединения с БД, в
304                 незашифрованном виде.
305                 Для вас может быть нежелательным сохранять такие данные в
306                 незащищенном текстовом файле, отправлять его через e-mail
307                 или любой другой носитель, который может быть прочитан
308                 потенциальным атакующим.
309                 Тот, кто прочитает сериализованный объект, не должен иметь
310                 возможности использовать его для получения
311                 несанкционированного доступа к БД.
312             </para>
313         </note>
315         <para>
316             Вы можете восстановить соединение для набора строк, используя
317             метод <code>setTable()</code>. Аргументом этого метода является
318             объект типа <code>Zend_Db_Table_Abstract</code>, который создается
319             вами. Создание объекта таблицы требует действующего соединения с БД,
320             поэтому при переустановке таблицы объект набора строк получает
321             доступ к БД. После этого вы сможете изменять значения объектов
322             строк, содержащихся в объекте набора строк и сохранять изменения
323             в БД.
324         </para>
326         <example id="zend.db.table.rowset.serialize.example.set-table">
328             <title>Пример восстановления соединения для набора строк</title>
330             <programlisting language="php"><![CDATA[
331 $rowset = unserialize($serializedRowset);
333 $bugs = new Bugs();
335 // Переустановка таблицы для набора строк,
336 // заодно восстанавливается соединение с БД
337 $rowset->setTable($bugs);
339 $row = $rowset->current();
341 // Теперь можно производить изменения в строке и сохранять их
342 $row->bug_status = 'FIXED';
343 $row->save();
345             </programlisting>
347         </example>
349         <para>
350             Восстановление соединения для набора строк через метод
351             <code>setTable()</code> делает то же самое для всех объектов
352             строк, содержащихся в этом наборе строк.
353         </para>
355     </sect2>
357     <sect2 id="zend.db.table.rowset.extending">
359         <title>Расширение класса набора строк</title>
361         <para>
362             Вы можете использовать альтернативный класс для наборов
363             строк путем расширения класса Zend_Db_Table_Rowset_Abstract.
364             Указывайте новый класс набора строк через имя в защищенном свойстве
365             <varname>$_rowsetClass</varname> класса таблицы или в массиве,
366             передаваемом в качестве аргумента конструктору объекта таблицы.
367         </para>
369         <example id="zend.db.table.rowset.extending.example">
371             <title>Указание своего класса набора строк</title>
373             <programlisting language="php"><![CDATA[
374 class MyRowset extends Zend_Db_Table_Rowset_Abstract
376     // ...кастомизация
379 // Укажите свой класс набора строк в качестве используемого по умолчанию
380 // во всех экземплярах класса таблицы
381 class Products extends Zend_Db_Table_Abstract
383     protected $_name = 'products';
384     protected $_rowsetClass = 'MyRowset';
387 // Или укажите свой класс набора строк для использования
388 // в конкретном экземпляре класса таблицы
390             </programlisting>
392         </example>
394         <para>
395             Стандартный класс Zend_Db_Rowset подходит для большинства случаев
396             использования. Тем не менее, может потребоваться добавить свою
397             логику в набор строк, специфический для данной таблицы.
398             Например, новый метод может вычислять агрегированное значение для
399             всех строк в наборе.
400         </para>
402         <example id="zend.db.table.rowset.extending.example-aggregate">
404             <title>Пример класса набора строк с новым методом</title>
406             <programlisting language="php"><![CDATA[
407 class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
409     /**
410      * Находит в текущем наборе строку с наибольшим
411      * значением в столбце 'updated_at'
412      */
413     public function getLatestUpdatedRow()
414     {
415         $max_updated_at = 0;
416         $latestRow = null;
417         foreach ($this as $row) {
418             if ($row->updated_at > $max_updated_at) {
419                 $latestRow = $row;
420             }
421         }
422         return $latestRow;
423     }
426 class Bugs extends Zend_Db_Table_Abstract
428     protected $_name = 'bugs';
429     protected $_rowsetClass = 'MyBugsRowset';
432             </programlisting>
434         </example>
436     </sect2>
439 </sect1>
440 <!--
441 vim:se ts=4 sw=4 et: