[ZF-10089] Zend_Log
[zend.git] / documentation / manual / ru / module_specs / Zend_Db_Table.xml
blob27836444f1fd60e8db0258c9beeda0670a7edea9
1 <sect1 id="zend.db.table">
3     <title>Zend_Db_Table</title>
5     <sect2 id="zend.db.table.introduction">
7         <title>Класс таблицы - введение</title>
9         <para>
10             Класс Zend_Db_Table является объектно-ориентированным интерфейсом к
11             таблицам баз данных. Он предоставляет методы для многих общих
12             операций над таблицами. Базовый класс является расширяемым, поэтому
13             вы можете добавлять свою логику.
14         </para>
16         <para>
17             Решением Zend_Db_Table является реализация паттерна
18             <ulink url="http://www.martinfowler.com/eaaCatalog/tableDataGateway.html">Table Data Gateway</ulink>.
19             Это решение также включает в себя класс, реализующий паттерн
20             <ulink url="http://www.martinfowler.com/eaaCatalog/rowDataGateway.html">Row Data Gateway</ulink>.
21         </para>
23     </sect2>
25     <sect2 id="zend.db.table.defining">
27         <title>Определение класса таблицы</title>
29         <para>
30             Для каждой таблицы в БД, к которой нужен доступ, определяется класс,
31             наследующий от Zend_Db_Table_Abstract.
32         </para>
34         <sect3 id="zend.db.table.defining.table-schema">
36             <title>Определение имени и схемы таблицы</title>
38             <para>
39                 Указывайте таблицу, для которой определен этот класс, используя
40                 защищенную переменную <varname>$_name</varname>. Переменная
41                 должна содержать имя таблицы в том виде, в котором она
42                 представлена в БД.
43             </para>
45             <example id="zend.db.table.defining.table-schema.example1">
47                 <title>Объявление класса таблицы с явным определением имени таблицы</title>
49                 <programlisting language="php"><![CDATA[
50 class Bugs extends Zend_Db_Table_Abstract
52     protected $_name = 'bugs';
54 ]]>
55                 </programlisting>
57             </example>
59             <para>
60                 Если вы не определили имя таблицы, то по умолчанию оно равно
61                 имени класса. Если вы предпочитаете этот путь, то имя класса
62                 должно иметь то же написание, что и имя таблицы в БД.
63             </para>
65             <example id="zend.db.table.defining.table-schema.example">
67                 <title>Объявление класса таблицы с неявным определением имени таблицы</title>
69                 <programlisting language="php"><![CDATA[
70 class bugs extends Zend_Db_Table_Abstract
72     // имя таблицы соответствует имени класса
74 ]]>
75                 </programlisting>
77             </example>
79             <para>
80                 Вы можете также объявить схему таблицы в защищенной переменной
81                 <varname>$_schema</varname> или через добавленное
82                 перед именем таблицы имя схемы в свойстве <varname>$_name</varname>.
83                 Схема, указанная с помощью свойства <varname>$_name</varname>,
84                 имеет более высокий приоритет, чем схема, объявленная с помощью
85                 свойства  <varname>$_schema</varname>. В некоторых СУРБД вместо
86                 термина "схема" используются термины "база данных" или
87                 "пространство таблиц", они используются аналогичным образом.
88             </para>
90             <example id="zend.db.table.defining.table-schema.example3">
92                 <title>Объявление класса таблицы со схемой</title>
94                 <programlisting language="php"><![CDATA[
95 // Первый способ:
96 class Bugs extends Zend_Db_Table_Abstract
98     protected $_schema = 'bug_db';
99     protected $_name   = 'bugs';
102 // Второй способ:
103 class Bugs extends Zend_Db_Table_Abstract
105     protected $_name = 'bug_db.bugs';
108 // Если в обоих свойствах $_name м $_schema была объявлена схема,
109 // то указанная в $_name имеет больший приоритет:
110 class Bugs extends Zend_Db_Table_Abstract
112     protected $_name   = 'bug_db.bugs';
113     protected $_schema = 'ignored';
116                 </programlisting>
118             </example>
120             <para>
121                 Схема и таблица могут быть указаны через конфигурационные
122                 директивы конструктора, которые замещают собой любые значения по
123                 умолчанию, определенные с помощью свойств <varname>$_name</varname> и
124                 <varname>$_schema</varname>. Спецификация схемы, данная через
125                 директиву <code>name</code>, замещает собой любое значение,
126                 переданное через опцию <code>schema</code>.
127             </para>
129             <example id="zend.db.table.defining.table-schema.example.constructor">
131                 <title>Объявление имен таблицы и схемы во время инстанцирования</title>
133                 <programlisting language="php"><![CDATA[
134 class Bugs extends Zend_Db_Table_Abstract
138 // Первый способ:
140 $tableBugs = new Bugs(array('name' => 'bugs', 'schema' => 'bug_db'));
142 // Второй способ:
144 $tableBugs = new Bugs(array('name' => 'bug_db.bugs');
146 // Если в обоих опциях 'name' и 'schema' была объявлена схема,
147 // то указанная в 'name' имеет больший приоритет:
149 $tableBugs = new Bugs(array('name' => 'bug_db.bugs',
150                             'schema' => 'ignored');
152                 </programlisting>
154             </example>
156             <para>
157                 Если вы не указали имя схемы, то по умолчанию это будет
158                 схема, к которой подключен ваш экземпляр адаптера БД.
159             </para>
161         </sect3>
163         <sect3 id="zend.db.table.defining.primary-key">
165             <title>Определение первичного ключа таблицы</title>
167             <para>
168                 Каждая таблица должна иметь первичный ключ. Вы можете объявить
169                 столбец для первичного ключа, используя защищенную переменную
170                 <varname>$_primary</varname>. Это может быть строка с именем одного
171                 столбца или массив имен столбцов, если первичный ключ является
172                 составным.
173             </para>
175             <example id="zend.db.table.defining.primary-key.example">
177                 <title>Пример определения первичного ключа</title>
179                 <programlisting language="php"><![CDATA[
180 class Bugs extends Zend_Db_Table_Abstract
182     protected $_name = 'bugs';
183     protected $_primary = 'bug_id';
186                 </programlisting>
188             </example>
190             <para>
191                 Если вы не задали первичный ключ, то Zend_Db_Table_Abstract
192                 пытается определить его, основываясь на данных, полученных
193                 через метод <code>describeTable()</code>.
194             </para>
196             <note>
198                 <para>
199                     Класс таблицы должен знать, какой столбец (или столбцы)
200                     используются для уникальной адресации строк. Если в
201                     классе таблицы или аргументах конструктора (а также в
202                     метаданных таблицы, полученных через метод
203                     <code>describeTable()</code>) не были указаны
204                     первичные ключи, то эта таблица не может использоваться
205                     через Zend_Db_Table.
206                 </para>
208             </note>
210         </sect3>
212         <sect3 id="zend.db.table.defining.setup">
214             <title>Переопределение методов установки таблицы</title>
216             <para>
217                 Когда создается экземпляр класса таблицы, конструктор вызывает
218                 ряд защищенных методов, инициализирующих метаданные для таблицы.
219                 Вы можете переопределить любые из этих методов для того, чтобы
220                 явно определить эти метаданные. Помните, что в конце должен
221                 вызываться родительский метод.
222             </para>
224             <example id="zend.db.table.defining.setup.example">
226                 <title>Пример переопределения метода _setupTableName()</title>
228                 <programlisting language="php">
229 <![CDATA[
230 class Bugs extends Zend_Db_Table_Abstract
232     protected function _setupTableName()
233     {
234         $this->_name = 'bugs';
235         parent::_setupTableName();
236     }
239                 </programlisting>
241             </example>
243             <para>
244                 Методы установки могут быть переопределены следующим образом:
245             </para>
247             <itemizedlist>
248                 <listitem>
249                     <para>
250                         <code>_setupDatabaseAdapter()</code> проверяет, был ли
251                         предоставлен адаптер БД, и извлекает используемый по
252                         умолчанию адаптер из реестра, если необходимо.
253                         Переопределив этот метод, вы можете
254                         установить адаптер БД из других источников.
255                     </para>
256                 </listitem>
257                 <listitem>
258                     <para>
259                         <code>_setupTableName()</code> по умолчанию получает имя
260                         таблицы из имени класса. Переопределив
261                         этот метод, вы можете установить имя таблицы до того,
262                         как будут произведены эти действия по умолчанию.
263                     </para>
264                 </listitem>
265                 <listitem>
266                     <para>
267                         <code>_setupMetadata()</code> устанавливает схему, если
268                         имя таблицы содержит структуру "schema.table", вызывает
269                         <code>describeTable()</code> для получения метаданных,
270                         по умолчанию определяет массив столбцов
271                         <varname>$_cols</varname>, полученных
272                         через <code>describeTable()</code>. Переопределелив этот
273                         метод, вы можете устанавливать столбцы самостоятельно.
274                     </para>
275                 </listitem>
276                 <listitem>
277                     <para>
278                         <code>_setupPrimaryKey()</code> по умолчанию
279                         устанавливает столбцы первичного ключа, полученные через
280                         <code>describeTable()</code>, и проверяет, входят ли
281                         столбцы первичного ключа в массив <varname>$_cols</varname>.
282                         Переопределив этот метод, вы можете устанавливать
283                         столбцы первичного ключа.
284                     </para>
285                 </listitem>
286             </itemizedlist>
288         </sect3>
290         <sect3 id="zend.db.table.initialization">
292             <title>Инициализация таблицы</title>
294             <para>
295                 Если при создании объекта таблицы требуется выполнять код,
296                 реализующий логику приложения, то вы можете поместить этот код в
297                 метод <code>init()</code>, который вызвается после того, как
298                 были обработаны все метаданные таблицы. Рекомендуется
299                 использовать этот способ вместо переопределения метода
300                 <code>__construct</code>, если только не требуется изменять
301                 метаданные программным путем.
303                 <example id="zend.db.table.defining.init.usage.example">
305                     <title>Пример использования метода init()</title>
307                     <programlisting language="php">
308 <![CDATA[
309 class Bugs extends Zend_Db_Table_Abstract
311     protected $_observer;
313     protected function init()
314     {
315         $this->_observer = new MyObserverClass();
316     }
319                     </programlisting>
321                 </example>
323             </para>
325         </sect3>
327     </sect2>
329     <sect2 id="zend.db.table.constructing">
331         <title>Создание экземпляра класса таблицы</title>
333         <para>
334             До того, как начать использование класса таблицы, создайте его
335             экземпляр, используя конструктор. Единственным аргументом
336             конструктора является массив опций. Наиболее важной опцией для
337             конструктора является экземпляр адаптера БД, представляющий текущее
338             соединение к какой-либо СУРБД. Есть три способа передачи адаптера БД
339             классу таблицы, и эти три способа описаны ниже:
340         </para>
342         <sect3 id="zend.db.table.constructing.adapter">
344             <title>Установка адаптера БД</title>
346             <para>
347                 Первым способом предоставления адаптера БД классу таблицы
348                 является передача объекта типа Zend_Db_Adapter_Abstract в
349                 массиве опций под ключом <code>'db'</code>.
350             </para>
352             <example id="zend.db.table.constructing.adapter.example">
354                 <title>Пример создания экземпляра таблицы с использованием объекта адаптера</title>
356                 <programlisting language="php">
357 <![CDATA[
358 $db = Zend_Db::factory('PDO_MYSQL', $options);
360 $table = new Bugs(array('db' => $db));
362                 </programlisting>
364             </example>
366         </sect3>
368         <sect3 id="zend.db.table.constructing.default-adapter">
370             <title>Установка используемого по умолчанию адаптера БД</title>
372             <para>
373                 Вторым способом предоставления адаптера БД классу таблицы
374                 является декларирование объекта типа Zend_Db_Adapter_Abstract
375                 как используемого по умолчанию для всех экземпляров таблиц в
376                 вашем приложении. Вы можете делать это через статический метод
377                 <code>Zend_Db_Table_Abstract::setDefaultAdapter()</code>. Его
378                 аргументом является объект типа Zend_Db_Adapter_Abstract.
379             </para>
381             <example id="zend.db.table.constructing.default-adapter.example">
383                 <title>Пример создания экземпляра таблицы с адаптером, используемым по умолчанию</title>
385                 <programlisting language="php">
386 <![CDATA[
387 $db = Zend_Db::factory('PDO_MYSQL', $options);
388 Zend_Db_Table_Abstract::setDefaultAdapter($db);
390 // Далее...
392 $table = new Bugs();
394                 </programlisting>
396             </example>
398             <para>
399                 Может быть удобным создавать объект адаптера БД в центральной
400                 части вашего приложения - например, в загрузочном коде - и затем
401                 сохранять его как адаптер, используемый по умолчанию. Это дает
402                 возможность быть уверенным в том, что во всем приложении
403                 используется один и тот же экземпляр адаптера. Но установка
404                 адаптера, используемого по умолчанию, ограничена одним
405                 экземпляром адаптера.
406             </para>
408         </sect3>
411         <sect3 id="zend.db.table.constructing.registry">
413             <title>Хранение адаптера БД в реестре</title>
415             <para>
416                 Третий способ передачи адаптера БД классу таблицы -
417                 передача строки в массиве опций под ключом <code>'db'</code>.
418                 Эта строка используется как ключ для статического экземпляра
419                 Zend_Registry, в котором под этим ключом должен храниться объект
420                 типа Zend_Db_Adapter_Abstract.
421             </para>
423             <example id="zend.db.table.constructing.registry.example">
425                 <title>Пример создания экземпляра таблицы с использованием ключа реестра</title>
427                 <programlisting language="php">
428 <![CDATA[
429 $db = Zend_Db::factory('PDO_MYSQL', $options);
430 Zend_Registry::set('my_db', $db);
432 // Далее...
434 $table = new Bugs(array('db' => 'my_db'));
436                 </programlisting>
438             </example>
440             <para>
441                 Как и в случае установки адаптера, используемого по умолчанию,
442                 это дает возможность быть уверенным в том, что во всем
443                 приложении используется один и тот же адаптер, но использование
444                 реестра является более гибким, т.к. вы можете хранить в
445                 нем более одного экземпляра адаптера. Экземпляр адаптера
446                 является индивидуальным для конкретной СУРБД и экземпляра БД.
447                 Если в вашем приложении необходимо подключаться к нескольким БД
448                 или даже различным СУРБД, то вам нужно использовать несколько
449                 адаптеров.
450             </para>
452         </sect3>
454     </sect2>
456     <sect2 id="zend.db.table.insert">
458         <title>Добавление строк в таблицу</title>
460         <para>
461             Вы можете использовать объект таблицы для добавления строк в таблицу
462             БД, на которой основан объект таблицы. Для этого используйте метод
463             <code>insert()</code> в объекте таблицы. Аргументом является
464             ассоциативный массив, содержащий имена столбцов и соответствующие им
465             значения.
466         </para>
468         <example id="zend.db.table.insert.example">
470             <title>Пример добавления строк в таблицу</title>
472             <programlisting language="php"><![CDATA[
473 $table = new Bugs();
475 $data = array(
476     'created_on'      => '2007-03-22',
477     'bug_description' => 'Something wrong',
478     'bug_status'      => 'NEW'
481 $table->insert($data);
483             </programlisting>
485         </example>
487         <para>
488             По умолчанию значения в вашем массиве данных добавляются как
489             буквенные значения, с использованием параметров. Если вам нужно,
490             чтобы они интерпретировались как выражения SQL, то необходимо
491             обозначить их отличие от простых строк. Для этого используйте
492             объекты типа Zend_Db_Expr.
493         </para>
495         <example id="zend.db.table.insert.example-expr">
497             <title>Пример добавления выражений в таблицу</title>
499             <programlisting language="php"><![CDATA[
500 $table = new Bugs();
502 $data = array(
503     'created_on'      => new Zend_Db_Expr('CURDATE()'),
504     'bug_description' => 'Something wrong',
505     'bug_status'      => 'NEW'
508             </programlisting>
510         </example>
512         <para>
513             В примере добавления строки выше предполагается, что таблица имеет
514             автоинкрементный первичный ключ. Это принятое по умолчанию поведение
515             Zend_Db_Table_Abstract, но есть и другие типы первичных ключей.
516             Следующий раздел описывает, как поддерживаются различные типы
517             первичных ключей.
518         </para>
520         <sect3 id="zend.db.table.insert.key-auto">
522             <title>Использование таблицы с автоинкрементным ключом</title>
524             <para>
525                 Автоинкрементный первичный ключ генерирует уникальное
526                 целочисленное значение, если вы опустите столбец для
527                 первичного ключа в своем операторе <code>INSERT</code>.
528             </para>
530             <para>
531                 Если защищенная переменная в Zend_Db_Table_Abstract
532                 <varname>$_sequence</varname> имеет булево значение <constant>TRUE</constant>,
533                 то класс предполагает, что таблица имеет автоинкрементный
534                 столбец.
535             </para>
537             <example id="zend.db.table.insert.key-auto.example">
539                 <title>Пример объявления таблицы с автоинкрементным первичным ключом</title>
541                 <programlisting language="php"><![CDATA[
542 class Bugs extends Zend_Db_Table_Abstract
544     protected $_name = 'bugs';
546     // Это значение по умолчанию присутствует в Zend_Db_Table_Abstract,
547     // устанавливать его не обязательно
548     protected $_sequence = true;
551                 </programlisting>
553             </example>
555             <para>
556                 Примерами СУРБД, поддерживающих автоинкрементные первичные ключи
557                 являются MySQL, Microsoft SQL Server и SQLite.
558             </para>
560             <para>
561                 PostgreSQL имеет нотацию <code>SERIAL</code>, которая неявно
562                 определяет последовательность, основанную на имени таблицы и
563                 столбца, и использует ее для генерации значений ключа при
564                 добавлении новых строк. IBM DB2 имеет нотацию
565                 <code>IDENTITY</code> которая работает аналогичным образом.
566                 Если вы используете одну из этих нотаций, то интерпретируйте
567                 свой класс Zend_Db_Table как имеющий автоинкрементный столбец,
568                 при этом члена <varname>$_sequence</varname> должен иметь значение
569                 <constant>TRUE</constant>.
570             </para>
572         </sect3>
574         <sect3 id="zend.db.table.insert.key-sequence">
576             <title>Использование таблицы с последовательностью</title>
578             <para>
579                 Последовательность (sequence) является объектом базы данных,
580                 генерирующим уникальные значения, которые могут
581                 использоваться как значения уникальных ключей в одной и более
582                 таблицах БД.
583             </para>
585             <para>
586                 Если вы присвоили <varname>$_sequence</varname> строковое значение,
587                 то Zend_Db_Table_Abstract считает строку именем объекта
588                 последовательности в БД. Последовательность запускается для
589                 генерации нового значения, и это значение используется в
590                 операции
591                 <code>INSERT</code>.
592             </para>
594             <example id="zend.db.table.insert.key-sequence.example">
596                 <title>Пример объявления таблицы с последовательностью</title>
598                 <programlisting language="php"><![CDATA[
599 class Bugs extends Zend_Db_Table_Abstract
601     protected $_name = 'bugs';
603     protected $_sequence = 'bug_sequence';
606                 </programlisting>
608             </example>
610             <para>
611                 Примерами СУРБД, поддерживающих объекты последовательностей
612                 являются Oracle, PostgreSQL и IBM DB2.
613             </para>
615             <para>
616                 PostgreSQL и IBM DB2 также имеют синтаксис, который неявно
617                 определяет последовательности и связывает их со столбцами.
618                 Если вы используете эту нотацию, то интерпретируйте таблицу
619                 как имеющую автоинкрементный ключевой столбец. Задавайте имя
620                 последовательности в виде строки только в тех случаях, когда вы
621                 собираетесь явно вызывать последовательности для получения
622                 следующего значения ключа.
623             </para>
625         </sect3>
627         <sect3 id="zend.db.table.insert.key-natural">
629             <title>Использование таблицы с естественным ключом</title>
631             <para>
632                 Некоторые таблицы имеют естественные ключи. Это означает, что
633                 ключ не генерируется автоматически таблицей или
634                 последовательностью. В этом случае вы должны установить значение
635                 первичного ключа.
636             </para>
638             <para>
639                 Если вы присвоили <varname>$_sequence</varname> булево значение
640                 <constant>FALSE</constant>, то Zend_Db_Table_Abstract считает, что
641                 таблица имеет естественный первичный ключ. Вы должны
642                 предоставлять значения для столбцов первичного ключа в массиве
643                 данных для метода <code>insert()</code>, иначе метод бросает
644                 исключение Zend_Db_Table_Exception.
645             </para>
647             <example id="zend.db.table.insert.key-natural.example">
649                 <title>Пример объявления таблицы с естественным ключом</title>
651                 <programlisting language="php"><![CDATA[
652 class BugStatus extends Zend_Db_Table_Abstract
654     protected $_name = 'bug_status';
656     protected $_sequence = false;
659                 </programlisting>
661             </example>
663             <note>
665                 <para>
666                     Все СУРБД поддерживают таблицы с естественными ключами.
667                     Примеры таблиц, часто объявляемых как имеющие естественные
668                     ключи: справочные таблицы, таблицы пересечений в отношениях
669                     "многие-ко-многим", большинство таблиц с составными
670                     ключами.
671                 </para>
673             </note>
675         </sect3>
677     </sect2>
679     <sect2 id="zend.db.table.update">
681         <title>Обновление строк в таблице</title>
683         <para>
684             Вы можете обновлять строки в таблице БД, используя метод
685             <code>update</code> класса таблицы. Этот метод принимает два
686             аргумента: первым является ассоциативный массив столбцов, которые
687             требуется изменить, и новых значений, присваиваемых этим столбцам;
688             вторым - выражение SQL, которое используется в предложении
689             <code>WHERE</code> в качестве условия изменения строки в операции
690             <code>UPDATE</code>.
691         </para>
693         <example id="zend.db.table.update.example">
695             <title>Пример обновления строк в таблице</title>
697             <programlisting language="php"><![CDATA[
698 $table = new Bugs();
700 $data = array(
701     'updated_on'      => '2007-03-23',
702     'bug_status'      => 'FIXED'
705 $where = $table->getAdapter()->quoteInto('bug_id = ?', 1234);
707 $table->update($data, $where);
709             </programlisting>
711         </example>
713         <para>
714             Поскольку метод таблицы <code>update()</code> в свою очередь
715             использует метод адаптера БД
716             <link linkend="zend.db.adapter.update"><code>update()</code></link>,
717             то второй аргумент может быть массивом SQL-выражений. Выражения
718             объединяются как булевы условия через оператор <code>AND</code>.
719         </para>
721         <note>
723             <para>
724                 Значения и идентификаторы в SQL-выражении не заключаются в
725                 кавычки автоматически. Если имеются значения или идентификаторы,
726                 которые требуют заключения в кавычки, то вы должны произвести
727                 его сами. Используйте методы <code>quote()</code>,
728                 <code>quoteInto()</code> и <code>quoteIdentifier()</code>
729                 адаптера БД.
730             </para>
732         </note>
734     </sect2>
736     <sect2 id="zend.db.table.delete">
738         <title>Удаление строк из таблицы</title>
740         <para>
741             Вы можете удалять строки из таблицы базы данных, используя метод
742             <code>delete()</code>. Этот метод принимает один аргумент,
743             являющийся SQL-выражением, который используется в предложении
744             <code>WHERE</code> в качестве условия, по которому удаляются строки.
745         </para>
747         <example id="zend.db.table.delete.example">
749             <title>Пример удаления строк из таблицы</title>
751             <programlisting language="php"><![CDATA[
752 $table = new Bugs();
754 $where = $table->getAdapter()->quoteInto('bug_id = ?', 1235);
756 $table->delete($where);
758             </programlisting>
760         </example>
762         <para>
763             Поскольку метод таблицы в свою очередь использует метод
764             <code>delete()</code> адаптера БД, то второй аргумент может быть
765             массивом SQL-выражений. Выражения объединяются как булевы условия
766             через оператор <code>AND</code>.
767         </para>
769         <note>
771             <para>
772                 Значения и идентификаторы в SQL-выражении не заключаются в
773                 кавычки автоматически. Если имеются значения или идентификаторы,
774                 которые требуют заключения в кавычки, то вы должны произвести
775                 его сами. Используйте методы <code>quote()</code>,
776                 <code>quoteInto()</code> и <code>quoteIdentifier()</code>
777                 адаптера БД.
778             </para>
780         </note>
782     </sect2>
784     <sect2 id="zend.db.table.find">
786         <title>Извлечение строк по первичному ключу</title>
788         <para>
789             Вы можете запрашивать из таблицы БД строки, соответствующие
790             определенным значениям в первичном ключе, используя метод
791             <code>find()</code>. Первым аргументом этого метода является
792             единственное значение или массив значений, сопоставляемых с
793             первичным ключом таблицы.
794         </para>
796         <example id="zend.db.table.find.example">
798             <title>Пример извлечения строк по значениям первичного ключа</title>
800             <programlisting language="php"><![CDATA[
801 $table = new Bugs();
803 // Запрос одной строки
804 // Возвращает набор строк (Rowset)
805 $rows = $table->find(1234);
807 // Запрос нескольких строк
808 // Также возвращает набор строк (Rowset)
809 $rows = $table->find(array(1234, 5678));
811 </programlisting>
813         </example>
815         <para>
816             Если вы задали одно значение, то метод вернет максимум одну
817             строку, потому что первичный ключ не может содержать повторяющиеся
818             значения и должна быть максимум одна строка в таблице БД,
819             соответствующая данному значению. Если вы задали несколько
820             значений, то метод вернет максимум столько строк, сколько
821             несовпадающих значений было задано.
822         </para>
824         <para>
825             Метод <code>find()</code> может возвращать меньше строк, чем было
826             задано значений для первичного ключа, если для некоторых значений
827             нет соответствующих строк в таблице БД. Метод может даже вернуть
828             нулевое количество строк. Поскольку количество возвращаемых строк
829             является переменным, то метод <code>find()</code> возвращает объект
830             типа Zend_Db_Table_Rowset_Abstract (набор строк).
831         </para>
833         <para>
834             Если первичный ключ является составным, т.e. он состоит из
835             нескольких столбцов, то можно задать добавочные столбцы как
836             дополнительные аргументы метода <code>find()</code>. Вы должны
837             передать столько аргументов, сколько столбцов в первичном
838             ключе таблицы.
839         </para>
841         <para>
842             Для того чтобы найти несколько строк с составным первичным ключом,
843             передавайте массив для каждого из аргументов. Все эти массивы должны
844             иметь одно и то же количество элементов. Значения из всех массивов
845             объединяются в "кортежи" в порядке следования; например, первые
846             элементы каждого массива определяют значение первого составного
847             первичного ключа, вторые элементы - второго составного ключа и т.д.
848         </para>
850         <example id="zend.db.table.find.example-compound">
852             <title>Пример извлечения строк по значениям составного первичного ключа</title>
854             <para>
855                 Вызов метода <code>find()</code> ниже для поиска нескольких
856                 строк может соответствовать двум строкам в БД. Первая строка
857                 должна иметь значение первичного ключа (1234, 'ABC'), вторая -
858                 (5678, 'DEF').
859             </para>
861             <programlisting language="php"><![CDATA[
862 class BugsProducts extends Zend_Db_Table_Abstract
864     protected $_name = 'bugs_products';
865     protected $_primary = array('bug_id', 'product_id');
868 $table = new BugsProducts();
870 // Запрашивает единственную строку через составной первичный ключ
871 // Возвращает набор строк (Rowset)
872 $rows = $table->find(1234, 'ABC');
874 // Запрашивает несколько строк через составной первичный ключ
875 // Также возвращает набор строк (Rowset)
876 $rows = $table->find(array(1234, 5678), array('ABC', 'DEF'));
878             </programlisting>
880         </example>
882     </sect2>
884     <sect2 id="zend.db.table.fetch-all">
886         <title>Извлечение наборов строк</title>
888         <sect3 id="zend.db.table.fetch-all.select">
890             <title>API для произведения выборки</title>
892             <para>
894                 <warning>
896                     <para>
897                         API для операций извлечения был изменен для того,
898                         чтобы объект <code>Zend_Db_Table_Select</code> мог
899                         изменять запрос. Тем не менее, не рекомендуемый
900                         сейчас вариант использования <code>fetchRow()</code> и
901                         <code>fetchAll()</code> будет работать без изменений.
902                     </para>
904                     <para>
905                         Следующие варианты являются корректными и
906                         функционально идентичными, но, тем не менее,
907                         рекомендуется обновить свой код с тем, чтобы
908                         получить преимущества нового подхода.
909                     </para>
911                     <para>
913                         <programlisting language="php">
914 <![CDATA[
915 // Извлечение набора строк
916 $rows = $table->fetchAll('bug_status = "NEW"', 'bug_id ASC', 10, 0);
917 $rows = $table->fetchAll($table->select()->where('bug_status = ?', 'NEW')
918                                          ->order('bug_id ASC')
919                                          ->limit(10, 0));
921 // Извлечение одной строки
922 $row = $table->fetchRow('bug_status = "NEW"', 'bug_id ASC');
923 $row = $table->fetchRow($table->select()->where('bug_status = ?', 'NEW')
924                                         ->order('bug_id ASC'));
926                         </programlisting>
928                     </para>
930                 </warning>
932             </para>
934             <para>
935                 Объект <classname>Zend_Db_Table_Select</classname> является
936                 расширением объекта <classname>Zend_Db_Select</classname>,
937                 который накладывает некоторые специфические ограничения
938                 на запрос. Ниже перечислены дополнительные возможности и
939                 ограничения этого класса:
940             </para>
942             <itemizedlist>
943                 <listitem>
944                     <para>
945                         Вы <emphasis>можете</emphasis> выбрать возвращение
946                         набора столбцов запросами fetchRow и fetchAll.
947                         Это дает преимущества в плане оптимизации там, где
948                         извлечение большого набора строк со всеми столбцами
949                         было бы не желательным.
950                     </para>
951                 </listitem>
953                 <listitem>
954                     <para>
955                         Вы <emphasis>можете</emphasis> указывать столбцы,
956                         которые определяют выражения в таблице. Но это также
957                         означает, что возвращаемый объект строки или набора
958                         строк будет доступен только для чтения и к нему не могут
959                         применяться операции сохранения. Объект строки
960                         <code>Zend_Db_Table_Row</code> со статусом
961                         <property>readOnly</property> будет бросать исключение
962                         при попытке произвести операцию сохранения (метод
963                         <code>save()</code>).
964                     </para>
965                 </listitem>
967                 <listitem>
968                     <para>
969                         Вы <emphasis>можете</emphasis> разрешить предложения
970                         JOIN в выборке для поиска в нескольких таблицах.
971                     </para>
972                 </listitem>
974                 <listitem>
975                     <para>
976                         Вы <emphasis>не можете</emphasis> указывать столбцы
977                         из присоединенных таблиц в качестве возвращаемых в
978                         строке/наборе строк. Попытка сделать это вызовет ошибку
979                         PHP. Это сделано для того, чтобы гарантировать
980                         целостность <code>Zend_Db_Table</code>, т.е.
981                         <code>Zend_Db_Table_Row</code> должен содержать
982                         столбцы только из той таблицы, которую представляет
983                         данный объект <code>Zend_Db_Table</code>.
984                     </para>
985                 </listitem>
986             </itemizedlist>
988             <para>
990                 <example id="zend.db.table.qry.rows.set.simple.usage.example">
992                     <title>Простое использование</title>
994                     <programlisting language="php">
995 <![CDATA[
996 $table = new Bugs();
998 $select = $table->select();
999 $select->where('bug_status = ?', 'NEW');
1001 $rows = $table->fetchAll($select);
1003                     </programlisting>
1005                 </example>
1007             </para>
1009             <para>
1010                 В данной компоненте поддерживается fluent interface,
1011                 поэтому пример выше может быть переписан в более краткой форме.
1012             </para>
1014             <para>
1016                 <example id="zend.db.table.qry.rows.set.fluent.interface.example">
1018                     <title>Пример использования fluent interface</title>
1020                     <programlisting language="php">
1021 <![CDATA[
1022 $table = new Bugs();
1024 $rows =
1025     $table->fetchAll($table->select()->where('bug_status = ?', 'NEW'));
1027                     </programlisting>
1029                 </example>
1031             </para>
1033         </sect3>
1035         <sect3 id="zend.db.table.fetch-all.usage">
1037             <title>Извлечение набора строк</title>
1039             <para>
1040                 Вы можете извлекать наборы строк, используя любое другое
1041                 условие, отличное от значения первичного ключа, через метод
1042                 <code>fetchAll()</code> класса таблицы. Этот метод возвращает
1043                 объект типа <code>Zend_Db_Table_Rowset_Abstract</code>.
1044             </para>
1046             <example id="zend.db.table.qry.rows.set.finding.row.example">
1048                 <title>Пример поиска строк по выражению</title>
1050                 <programlisting language="php">
1051 <![CDATA[
1052 $table = new Bugs();
1054 $select = $table->select()->where('bug_status = ?', 'NEW');
1056 $rows = $table->fetchAll($select);
1058                 </programlisting>
1060             </example>
1062             <para>
1063                 Вы можете также передавать условие для сортировки, которое
1064                 используется в предложении <code>ORDER BY</code>, и
1065                 целочисленные значения смещения и количества строк для
1066                 предложения <code>LIMIT</code> или эквивалентной
1067                 ему логики в СУРБД, не поддерживающих синтаксис
1068                 <code>LIMIT</code>.
1069             </para>
1071             <example id="zend.db.table.fetch-all.example2">
1073                 <title>Пример поиска строк по выражению</title>
1075                 <programlisting language="php">
1076 <![CDATA[
1077 $table = new Bugs();
1079 $order  = 'bug_id';
1081 // Требуется вернуть строки начиная с 21-ой и кончая 30-й
1082 $count  = 10;
1083 $offset = 20;
1085 $select = $table->select()->where(array('bug_status = ?' => 'NEW'))
1086                           ->order($order)
1087                           ->limit($count, $offset);
1089 $rows = $table->fetchAll($select);
1091                 </programlisting>
1093             </example>
1095             <para>
1096                 Все агрументы в примере выше являются опциональными. Если вы
1097                 опустите предложение ORDER, то строки из таблицы будут
1098                 возвращаться в непредсказуемом порядке. Если не было
1099                 установлено предложение LIMIT, то вы получите все
1100                 соответствующие предложению WHERE строки из таблицы.
1101             </para>
1103         </sect3>
1105         <sect3 id="zend.db.table.advanced.usage">
1107             <title>Расширенное использование</title>
1109             <para>
1110                 Для более точных и оптимизированных запросов может
1111                 потребоваться ограничить количество столбцов, возвращаемых в
1112                 строке/наборе строк. Это может быть достигнуто путем передачи
1113                 предложения FROM объекту выборки.
1114             </para>
1116             <para>
1118                 <example id="zend.db.table.qry.rows.set.retrieving.a.example">
1120                     <title>Извлечение определенных столбцов</title>
1122                     <programlisting language="php"><![CDATA[
1123 $table = new Bugs();
1125 $select = $table->select();
1126 $select->from($table, array('bug_id', 'bug_description'))
1127        ->where('bug_status = ?', 'NEW');
1129 $rows = $table->fetchAll($select);
1131                     </programlisting>
1133                 </example>
1135             </para>
1137             <para>
1139                 <important>
1141                     <para>
1142                         Полученный набор строк будет содержать строки, которые
1143                         по-прежнему являются "рабочими", только они
1144                         содержат не все столбцы таблицы. Если для неполной
1145                         строки был вызван метод save(), то будут изменены только
1146                         доступные в объекте столбцы.
1147                     </para>
1149                 </important>
1151                 Вы можете также указывать выражения в предложении FROM, но в
1152                 этом случае будуте получать строки/наборы строк,
1153                 доступные только для чтения. В этом примере мы будем возвращать
1154                 строки из таблицы Bugs, которые показывают количество
1155                 ошибок, сообщенное конкретным пользователем. Обратите
1156                 внимание на предложение GROUP. Столбец 'count' будет доступен в
1157                 объекте строки, и к нему можно обращаться так же, как если бы он
1158                 был частью схемы.
1159             </para>
1161             <para>
1163                 <example id="zend.db.table.qry.rows.set.retrieving.b.example">
1165                     <title>Извлечение выражений как столбцов</title>
1167                     <programlisting language="php"><![CDATA[
1168 $table = new Bugs();
1170 $select = $table->select();
1171 $select->from($table,
1172               array('COUNT(reported_by) as `count`', 'reported_by'))
1173        ->where('bug_status = ?', 'NEW')
1174        ->group('reported_by');
1176 $rows = $table->fetchAll($select);
1178                     </programlisting>
1180                 </example>
1182                 Вы можете использовать поиск как часть вашего запроса
1183                 для дальнейшей детализации ваших операций извлечения.
1184                 В этом примере таблица Accounts используется для
1185                 поиска всех новых ошибок, о которых сообщил пользователь 'Bob'.
1186             </para>
1188             <para>
1190                 <example id="zend.db.table.qry.rows.set.refine.example">
1192                     <title>Использование таблицы поиска для фильтрации результатов, возвращаемых fetchAll()</title>
1194                     <programlisting language="php"><![CDATA[
1195 $table = new Bugs();
1197 $select = $table->select();
1198 $select->where('bug_status = ?', 'NEW')
1199        ->join('accounts', 'accounts.account_name = bugs.reported_by')
1200        ->where('accounts.account_name = ?', 'Bob');
1202 $rows = $table->fetchAll($select);
1204                     </programlisting>
1206                 </example>
1208             </para>
1210             <para>
1211                 Класс <classname>Zend_Db_Table_Select</classname> главным
1212                 образом используется для соблюдения и проверки
1213                 корректности запроса.
1214                 Тем не менее, могут быть определенные случаи, когда
1215                 нужна большая гибкость компоненты Zend_Db_Table_Row и
1216                 не требуется доступная для чтения или удаления строка.
1217                 Для этого отдельного случая использования возможно получение
1218                 строки/набора строк путем передачи значения false методу
1219                 setIntegrityCheck().
1220                 В результате строка/набор строк будет возвращаться в
1221                 "заблокированном" состоянии, это значит, что save(),
1222                 delete() и методы для установки значений полей будут бросать
1223                 исключения.
1224             </para>
1226             <example id="zend.db.table.qry.rows.set.integrity.example">
1228                 <title>Отключение проверки целостности в Zend_Db_Table_Select для получения объединенных строк</title>
1230                 <programlisting><![CDATA[
1231 $table = new Bugs();
1233 $select = $table->select()->setIntegrityCheck(false);
1234 $select->where('bug_status = ?', 'NEW')
1235        ->join('accounts',
1236               'accounts.account_name = bugs.reported_by',
1237               'account_name')
1238        ->where('accounts.account_name = ?', 'Bob');
1240 $rows = $table->fetchAll($select);
1242                 </programlisting>
1244             </example>
1246         </sect3>
1248     </sect2>
1250     <sect2 id="zend.db.table.fetch-row">
1252         <title>Извлечение одной строки</title>
1254         <para>
1255             Вы можете запрашивать одну строку, используя условия, аналогичные
1256             тем, что используются в методе <code>fetchAll()</code>.
1257         </para>
1259         <example id="zend.db.table.fetch-row.example1">
1261             <title>Пример поиска одной строки по выражению</title>
1263             <programlisting language="php"><![CDATA[
1264 $table = new Bugs();
1266 $select  = $table->select()->where('bug_status = ?', 'NEW')
1267                            ->order('bug_id');
1269 $row = $table->fetchRow($select);
1271             </programlisting>
1273         </example>
1275         <para>
1276             Этот метод возвращает объект типа Zend_Db_Table_Row_Abstract. Если
1277             по заданному вами условию поиска не найдено ни одной строки в
1278             таблице БД, то <code>fetchRow()</code> вернет значение
1279             <constant>NULL</constant>.
1280         </para>
1282     </sect2>
1284     <sect2 id="zend.db.table.info">
1286         <title>Получение метаданных таблицы</title>
1288         <para>
1289             Класс Zend_Db_Table_Abstract предоставляет некоторую информацию о
1290             его метаданных. Метод <code>info()</code> возвращает массив с
1291             данными о таблице, ее столбцах, первичном ключе и другие метаданные.
1292         </para>
1294         <example id="zend.db.table.info.example">
1296             <title>Пример получения имени таблицы</title>
1298             <programlisting language="php">
1299 <![CDATA[
1300 $table = new Bugs();
1302 $info = $table->info();
1304 echo "The table name is " . $info['name'] . "\n";
1306             </programlisting>
1308         </example>
1310         <para>
1311             Ключи массива, возвращаемого методом <code>info()</code>, описаны
1312             ниже.
1313         </para>
1315         <itemizedlist>
1316             <listitem>
1317                 <para>
1318                     <emphasis>name</emphasis> => имя таблицы
1319                 </para>
1320             </listitem>
1321             <listitem>
1322                 <para>
1323                     <emphasis>cols</emphasis> =>
1324                     массив имен столбцов в таблице
1325                 </para>
1326             </listitem>
1327             <listitem>
1328                 <para>
1329                     <emphasis>primary</emphasis> =>
1330                     массив имен столбцов в первичном ключе
1331                 </para>
1332             </listitem>
1333             <listitem>
1334                 <para>
1335                     <emphasis>metadata</emphasis> =>
1336                     ассоциативный массив, включающий в себя имена столбцов и
1337                     соответствующие им данные о столбцах. Это информация,
1338                     возвращаемая методом <code>describeTable()</code>.
1339                 </para>
1340             </listitem>
1341             <listitem>
1342                 <para>
1343                     <emphasis>rowClass</emphasis> => имя
1344                     определенного класса, используемого для объектов строк,
1345                     возвращаемых методами данного экземпляра таблицы. По
1346                     умолчанию это Zend_Db_Table_Row.
1347                 </para>
1348             </listitem>
1349             <listitem>
1350                 <para>
1351                     <emphasis>rowsetClass</emphasis> =>
1352                     имя определенного класса, используемого для объектов
1353                     наборов строк, возвращаемых методами данного экземпляра
1354                     таблицы. По умолчанию это Zend_Db_Table_Rowset.
1355                 </para>
1356             </listitem>
1357             <listitem>
1358                 <para>
1359                     <emphasis>referenceMap</emphasis> =>
1360                     ассоциативный массив с данными о ссылках на другие таблицы.
1361                     См. <xref linkend="zend.db.table.relationships.defining" />.
1362                 </para>
1363             </listitem>
1364             <listitem>
1365                 <para>
1366                     <emphasis>dependentTables</emphasis> =>
1367                     массив имен классов таблиц, на которые ссылается данная
1368                     таблица. См.
1369                     <xref linkend="zend.db.table.relationships.defining" />.
1370                 </para>
1371             </listitem>
1372             <listitem>
1373                 <para>
1374                     <emphasis>schema</emphasis> =>
1375                     имя схемы (базы данных, пространства таблиц) для данной
1376                     таблицы.
1377                 </para>
1378             </listitem>
1379         </itemizedlist>
1381     </sect2>
1383     <sect2 id="zend.db.table.metadata.caching">
1385         <title>Кэширование метаданных таблицы</title>
1387         <para>
1388             По умолчанию <code>Zend_Db_Table_Abstract</code> производит запрос к
1389             БД для определения <link linkend="zend.db.table.info">метаданных
1390             таблицы</link> во время инстанцирования объекта таблицы. Т.е. когда
1391             создается новый объект таблицы, поведением по умолчанию является
1392             извлечение метаданных таблицы из БД через метод
1393             <code>describeTable()</code>.
1394         </para>
1396         <para>
1397             В некоторых условиях, особенно когда к одной и той же таблице БД
1398             создается много объектов таблиц, произведение запросов для
1399             получения метаданных для каждого экземпляря может быть нежелательным
1400             с точки зрения производительности. В таких случаях можно производить
1401             кэширование метаданных таблицы, полученных из БД.
1402         </para>
1404         <para>
1405             Есть два основных способа кэширования:
1407             <itemizedlist>
1408                 <listitem>
1409                     <para>
1410                         <emphasis>Вызов метода
1411                         Zend_Db_Table_Abstract::setDefaultMetadataCache()</emphasis>
1412                         - Это позволяет разработчику единовременно установить
1413                         объект кэша, используемый в всех классах таблиц.
1414                     </para>
1415                 </listitem>
1416                 <listitem>
1417                     <para>
1418                         <emphasis>Конфигурирование
1419                         Zend_Db_Table_Abstract::__construct()</emphasis> - Это
1420                         позволяет разработчику установить объект кэша для
1421                         определенного экземпляра класса таблицы.
1422                     </para>
1423                 </listitem>
1424             </itemizedlist>
1426             В обоих случаях определением кэша может быть <constant>NULL</constant>
1427             (т.е. не используется кэширование) или экземпляр класса
1428             <link linkend="zend.cache.frontends.core"><code>Zend_Cache_Core</code></link>.
1429             Эти методы могут использоваться вместе для того, чтобы
1430             использовать по умолчанию определенный объект кэша и при этом иметь
1431             возможность изменять его для конкретного объекта таблицы.
1432         </para>
1434         <example id="zend.db.table.metadata.caching-default">
1436             <title>Кэширование метаданных по умолчанию для всех объектов таблиц</title>
1438             <para>
1439                 Следующий код показывает, как установить объект кэша,
1440                 используемый по умолчанию во всех объектах таблиц:
1441             </para>
1443             <programlisting language="php"><![CDATA[
1444 // Сначала создается объект кэша
1445 $frontendOptions = array(
1446     'automatic_serialization' => true
1447     );
1449 $backendOptions  = array(
1450     'cacheDir'                => 'cacheDir'
1451     );
1453 $cache = Zend_Cache::factory('Core',
1454                              'File',
1455                              $frontendOptions,
1456                              $backendOptions);
1459 // Далее, объект кэша устанавливается в качестве используемого
1460 // во всех объектах таблиц
1461 Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
1464 // Класс таблицы
1465 class Bugs extends Zend_Db_Table_Abstract
1467     // ...
1471 // Каждый экземпляр таблицы Bugs теперь использует
1472 // кэширование метаданных по умолчанию
1473 $bugs = new Bugs();
1475             </programlisting>
1477         </example>
1479         <example id="zend.db.table.metadata.caching-instance">
1481             <title>Кэширование метаданных для одного объекта таблицы</title>
1483             <para>
1484                 Следующий код показывает, как устанавливается кэширование
1485                 метаданных для одного конкретного объекта таблицы:
1486             </para>
1488             <programlisting language="php"><![CDATA[
1489 // Сначала создается объект кэша
1490 $frontendOptions = array(
1491     'automatic_serialization' => true
1492     );
1494 $backendOptions  = array(
1495     'cacheDir'                => 'cacheDir'
1496     );
1498 $cache = Zend_Cache::factory('Core',
1499                              'File',
1500                              $frontendOptions,
1501                              $backendOptions);
1503 // Класс таблицы
1504 class Bugs extends Zend_Db_Table_Abstract
1506     // ...
1510 // Экземпляр конфигурируется при инстанцировании
1511 $bugs = new Bugs(array('metadataCache' => $cache));
1513             </programlisting>
1515         </example>
1517         <note>
1519             <title>Автоматическая сериализация через фронтэнд кэша</title>
1521             <para>
1522                 Поскольку информация, возвращаемая методом адаптера
1523                 describeTable(), является массивом, то убедитесь, что опция
1524                 <code>automatic_serialization</code> установлена в
1525                 <constant>TRUE</constant> для фронтэнда <code>Zend_Cache_Core</code>.
1526             </para>
1528         </note>
1530         <para>
1531             Несмотря на то, что в примерах выше используется
1532             <code>Zend_Cache_Backend_File</code>, разработчики могут
1533             использовать другие бэкэнды, наиболее подходящие в данной ситуации.
1534             Более подробную информацию читайте в разделе
1535             <link linkend="zend.cache">Zend_Cache</link>.
1536         </para>
1538     </sect2>
1540     <sect2 id="zend.db.table.extending">
1542         <title>Расширение класса таблицы</title>
1544         <sect3 id="zend.db.table.extending.row-rowset">
1546             <title>Использование собственных классов строки и набора строк</title>
1548             <para>
1549                 По умолчанию методы класса таблицы возвращают наборы строк в
1550                 экземплярах класса Zend_Db_Table_Rowset, и эти наборы строк
1551                 содержат в себе коллекции экземпляров класса Zend_Db_Table_Row.
1552                 Вы можете указать альтернативные классы, используемые вместо
1553                 них, но в любом случае они должны наследовать от классов
1554                 Zend_Db_Table_Rowset_Abstract и Zend_Db_Table_Row_Abstract
1555                 соответственно.
1556             </para>
1558             <para>
1559                 Вы можете указать классы строки и набора строк в
1560                 массиве опций конструктора таблицы под ключами
1561                 <code>'rowClass'</code> и <code>'rowsetClass'</code>
1562                 соответственно. Задавайте имена классов в виде обычных строк.
1563             </para>
1565             <example id="zend.db.table.extending.row-rowset.example">
1567                 <title>Пример указания классов строки и набора строк</title>
1569                 <programlisting language="php"><![CDATA[
1570 class My_Row extends Zend_Db_Table_Row_Abstract
1572     ...
1575 class My_Rowset extends Zend_Db_Table_Rowset_Abstract
1577     ...
1580 $table = new Bugs(
1581     array(
1582         'rowClass'    => 'My_Row',
1583         'rowsetClass' => 'My_Rowset'
1584     )
1587 $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
1589 // Возвращает объект типа My_Rowset,
1590 // содержащий массив объектов типа My_Row
1591 $rows = $table->fetchAll($where);
1593                 </programlisting>
1595             </example>
1597             <para>
1598                 Вы можете сменить используемые классы, указав их через методы
1599                 <code>setRowClass()</code> и <code>setRowsetClass()</code>.
1600                 Это изменение применяется к создаваемым впоследствии строкам и
1601                 наборам строк и не влияет на класс объектов строк и наборов
1602                 строк, созданных ранее.
1603             </para>
1605             <example id="zend.db.table.extending.row-rowset.example2">
1607                 <title>Пример смены используемых для строк и наборов строк классов</title>
1609                 <programlisting language="php"><![CDATA[
1610 $table = new Bugs();
1612 $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
1614 // Возвращает объект типа Zend_Db_Table_Rowset,
1615 // содержащий массив объектов типа Zend_Db_Table_Row.
1616 $rowsStandard = $table->fetchAll($where);
1618 $table->setRowClass('My_Row');
1619 $table->setRowsetClass('My_Rowset');
1621 // Возвращает объект типа My_Rowset,
1622 // содержащий массив объектов типа My_Row.
1623 $rowsCustom = $table->fetchAll($where);
1625 // Объект $rowsStandard по прежнему существует и не изменился.
1627                 </programlisting>
1629             </example>
1631             <para>
1632                 Более подробную информацию о классах строки и набора строк
1633                 ищите в <xref linkend="zend.db.table.row" /> и
1634                 <xref linkend="zend.db.table.rowset" />.
1635             </para>
1637         </sect3>
1639         <sect3 id="zend.db.table.extending.insert-update">
1641             <title>Определение собственной логики для добавления, обновления и удаления строк</title>
1643             <para>
1644                 Вы можете переопределить методы <code>insert()</code> и
1645                 <code>update()</code> в своем классе таблицы. Это дает
1646                 возможность реализовать собственный
1647                 код, который исполняется до того, как будет выполнена операция с
1648                 БД. Всегда вызывайте метод родительского класса после своих
1649                 действий.
1650             </para>
1652             <example id="zend.db.table.extending.insert-update.example">
1654                 <title>Собственная логика для управления отметками времени</title>
1656                 <programlisting language="php"><![CDATA[
1657 class Bugs extends Zend_Db_Table_Abstract
1659     protected $_name = 'bugs';
1661     public function insert(array $data)
1662     {
1663         // добавление timestamp
1664         if (empty($data['created_on'])) {
1665             $data['created_on'] = time();
1666         }
1667         return parent::insert($data);
1668     }
1670     public function update(array $data, $where)
1671     {
1672         // добавление timestamp
1673         if (empty($data['updated_on'])) {
1674             $data['updated_on'] = time();
1675         }
1676         return parent::update($data, $where);
1677     }
1680                 </programlisting>
1682             </example>
1684             <para>
1685                 Вы можете также переопределить метод <code>delete()</code>.
1686             </para>
1688         </sect3>
1690         <sect3 id="zend.db.table.extending.finders">
1692             <title>Определение собственных методов для поиска</title>
1694             <para>
1695                 Вы можете реализовать собственные методы запросов в своем классе
1696                 таблицы, если приходится часто делать запросы к таблице с одними
1697                 и теми же условиями. Большинство запросов могут быть написаны с
1698                 использованием <code>fetchAll()</code>, но это требует написания
1699                 повторяющегося кода для формирования условий запроса в том
1700                 случае, если вам нужно выполнять запрос в нескольких местах
1701                 вашего приложения. Поэтому будет удобным добавить метод в класс
1702                 таблицы для выполнения часто используемых запросов к таблице.
1703             </para>
1705             <example id="zend.db.table.extending.finders.example">
1707                 <title>Метод для поиска ошибок с определенным статусом</title>
1709                 <programlisting language="php"><![CDATA[
1710 class Bugs extends Zend_Db_Table_Abstract
1712     protected $_name = 'bugs';
1714     public function findByStatus($status)
1715     {
1716         $where = $this->getAdapter()->quoteInto('bug_status = ?', $status);
1717         return $this->fetchAll($where, 'bug_id');
1718     }
1721                 </programlisting>
1723             </example>
1725         </sect3>
1727         <sect3 id="zend.db.table.extending.inflection">
1729             <title>Определение инфлекции в Zend_Db_Table</title>
1731             <para>
1732                 Некоторые разработчики предпочитают, чтобы имя класса таблицы
1733                 сопоставлялось с именем таблицы в СУРБД с применением
1734                 преобразования, называемого <emphasis>инфлекцией</emphasis>.
1735             </para>
1737             <para>
1738                 Например, если имя вашего класса таблицы -
1739                 "<code>BugsProducts</code>", то класс должен соответствовать
1740                 физической таблице в БД с названием
1741                 "<code>bugs_products</code>", если вы не произвели явное
1742                 объявление свойства класса <varname>$_name</varname>. В данном
1743                 преобразовании имя класса в формате "CamelCase" должно
1744                 приводиться к нижнему регистру с разделением слов символом
1745                 подчеркивания.
1746             </para>
1748             <para>
1749                 Вы можете указать имя таблицы БД независимо то имени класса,
1750                 объявив его в свойстве <varname>$_name</varname> во всех классах этой
1751                 таблицы.
1752             </para>
1754             <para>
1755                 Zend_Db_Table_Abstract не производит инфлекцию при получении
1756                 имени таблицы. Если вы опустите
1757                 объявление свойства <varname>$_name</varname> в своем классе таблицы,
1758                 то класс будет соответствовать таблице в БД с точно таким же
1759                 именем, как и у него.
1760             </para>
1762             <para>
1763                 Было бы неуместным использовать преобразование идентификаторов
1764                 из БД, поскольку это может привести к неоднозначности или
1765                 сделать некоторые идентификаторы недоступными.
1766                 Использование SQL-идентификаторов в том виде, в котором они
1767                 присутствуют в БД, делает Zend_Db_Table_Abstract проще и гибче в
1768                 использовании.
1769             </para>
1771             <para>
1772                 Если вы предпочитаете использовать инфлекцию, то должны
1773                 реализовать преобразование сами, переопределив метод
1774                 <code>_setupTableName()</code> в своем классе таблицы. Одним из
1775                 возможных способов является определение абстрактного класса,
1776                 наследующего от Zend_Db_Table_Abstract, и объявление
1777                 классов остальных таблиц как наследующих от этого нового
1778                 класса.
1779             </para>
1781             <example id="zend.db.table.extending.inflection.example">
1783                 <title>Пример абстрактного класса таблицы, реализующего инфлекцию</title>
1785                 <programlisting language="php"><![CDATA[
1786 abstract class MyAbstractTable extends Zend_Db_Table_Abstract
1788     protected function _setupTableName()
1789     {
1790         if (!$this->_name) {
1791             $this->_name = myCustomInflector(get_class($this));
1792         }
1793         parent::_setupTableName();
1794     }
1797 class BugsProducts extends MyAbstractTable
1801                 </programlisting>
1803             </example>
1805             <para>
1806                 Реализация функций для произведения инфлекционного
1807                 преобразования возлагается на разработчика. Zend Framework не
1808                 предоставляет для этих целей готовых функций.
1809             </para>
1811         </sect3>
1813     </sect2>
1815 </sect1>
1816 <!--
1817 vim:se ts=4 sw=4 et: