[ZF-10089] Zend_Log
[zend.git] / documentation / manual / ru / module_specs / Zend_Db_Adapter.xml
blob40fa9f3afe0b6687063d0f788d06ef3e1d7e1808
1 <sect1 id="zend.db.adapter">
3     <title>Zend_Db_Adapter</title>
5     <para>
6         Zend_Db и его родственные классы предоставляют простой интерфейс к базам
7         данных SQL в Zend Framework. Zend_Db_Adapter является базовым классом,
8         который должен использоваться для подключения приложения PHP
9         к СУРБД. Существуют различные классы адаптеров для наиболее часто
10         используемых СУРБД.
11     </para>
13     <para>
14         Адаптеры Zend_Db создают мост между общим интерфейсом и расширениями
15         PHP от конкретных поставщиков для того, чтобы можно
16         было единовременно писать приложения на PHP и затем переключаться между
17         различными СУРБД с наименьшими усилиями.
18     </para>
20     <para>
21         Интерфейс класса адаптера подобен интерфейсу расширения
22         <ulink url="http://www.php.net/pdo">PHP Data Objects (PDO)</ulink>.
23         Zend_Db предоставляет классы адаптеров к драйверам PDO для следующих
24         популярных СУРБД:
25     </para>
27     <itemizedlist>
28         <listitem>
29             <para>
30                 IBM DB2 и Informix Dynamic Server (IDS), с использованием
31                 расширения <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
32             </para>
33         </listitem>
34         <listitem>
35             <para>
36                 MySQL, с использованием расширения <ulink url="http://www.php.net/pdo-mysql">pdo_mysql</ulink>
37             </para>
38         </listitem>
39         <listitem>
40             <para>
41                 Microsoft SQL Server, с использованием расширения <ulink url="http://www.php.net/pdo-mssql">pdo_mssql</ulink>
42             </para>
43         </listitem>
44         <listitem>
45             <para>
46                 Oracle, с использованием расширения <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
47             </para>
48         </listitem>
49         <listitem>
50             <para>
51                 PostgreSQL, с использованием расширения <ulink url="http://www.php.net/pdo-pgsql">pdo_pgsql</ulink>
52             </para>
53         </listitem>
54         <listitem>
55             <para>
56                 SQLite, с использованием расширения <ulink url="http://www.php.net/pdo-sqlite">pdo_sqlite</ulink>
57             </para>
58         </listitem>
59     </itemizedlist>
61     <para>
62         Кроме этого, Zend_Db предоставляет классы адаптеров, использующие расширения PHP для следующих распространенных СУРБД:
63     </para>
65     <itemizedlist>
66         <listitem>
67             <para>
68                 MySQL, с использованием расширения <ulink url="http://www.php.net/mysqli">mysqli</ulink>
69             </para>
70         </listitem>
71         <listitem>
72             <para>
73                 Oracle, с использованием расширения <ulink url="http://www.php.net/oci8">oci8</ulink>
74             </para>
75         </listitem>
76         <listitem>
77             <para>
78                 IBM DB2, с использованием расширения <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
79             </para>
80         </listitem>
81         <listitem>
82             <para>
83                 Firebird/Interbase, с использованием расширения <ulink url="http://www.php.net/ibase">php_interbase</ulink>
84             </para>
85         </listitem>
86     </itemizedlist>
88     <note>
89         <para>
90             Все адаптеры Zend_Db используют расширения PHP. Вы должны иметь
91             включенным соответствующее расширение в вашей среде PHP для
92             использования адаптера Zend_Db. Например, если вы используете
93             какой-либо из адаптеров PDO Zend_Db, то нужно включить как
94             расширение PDO, так и драйвер PDO для используемой вами СУРБД.
95         </para>
96     </note>
98     <sect2 id="zend.db.adapter.connecting">
100         <title>Соединение с БД с использованием адаптера</title>
102         <para>
103             Этот раздел описывает, как создавать экземпляр адаптера БД. Это
104             соответствует созданию соединения с сервером СУРБД из вашего
105             приложения PHP.
106         </para>
108         <sect3 id="zend.db.adapter.connecting.constructor">
110             <title>Использование конструктора адаптера Zend_Db</title>
112             <para>
113                 Вы можете создавать экземпляр адаптера с помощью его
114                 конструктора. Конструктор адаптера принимает единственный
115                 аргумент, который является массивом параметров, использующихся
116                 для описания соединения.
117             </para>
119             <example id="zend.db.adapter.connecting.constructor.example">
120                 <title>Использование конструктора адаптера</title>
121                 <programlisting language="php"><![CDATA[
122 $db = new Zend_Db_Adapter_Pdo_Mysql(array(
123     'host'     => '127.0.0.1',
124     'username' => 'webuser',
125     'password' => 'xxxxxxxx',
126     'dbname'   => 'test'
129                 </programlisting>
130             </example>
132         </sect3>
134         <sect3 id="zend.db.adapter.connecting.factory">
136             <title>Использование фабрики Zend_Db</title>
138             <para>
139                 Вместо непосредственного использования конструктора
140                 адаптера можно создавать экземпляры адаптера, применяя
141                 статический метод <code>Zend_Db::factory()</code>. Этот метод
142                 динамически загружает файл класса адаптера, используя
143                 <link linkend="zend.loader.load.class">Zend_Loader::loadClass()</link>.
144             </para>
146             <para>
147                 Первым аргументом является строка с базовым именем класса
148                 адаптера. Например, строка 'Pdo_Mysql' соответствует классу
149                 Zend_Db_Adapter_Pdo_Mysql. Вторым аргументом является тот же
150                 массив параметров, который вы должны были бы передать
151                 конструктору адаптера.
152             </para>
154             <example id="zend.db.adapter.connecting.factory.example">
155                 <title>Использование метода-фабрики адаптеров</title>
156                 <programlisting language="php"><![CDATA[
157 // Нам не нужно использовать следующее предложение, поскольку
158 // файл Zend_Db_Adapter_Pdo_Mysql будет загружен через
159 // метод-фабрику Zend_Db
161 // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
163 // Автоматически загружает класс Zend_Db_Adapter_Pdo_Mysql
164 // и создает его экземпляр.
165 $db = Zend_Db::factory('Pdo_Mysql', array(
166     'host'     => '127.0.0.1',
167     'username' => 'webuser',
168     'password' => 'xxxxxxxx',
169     'dbname'   => 'test'
172                 </programlisting>
173             </example>
175             <para>
176                 Если вы создали собственный класс, расширяющий
177                 Zend_Db_Adapter_Abstract, но не дали ему имя, начинающееся с
178                 префикса "Zend_Db_Adapter", то можете использовать метод
179                 <code>factory()</code> для загрузки своего адаптера, указав
180                 ведущую часть имени класса адаптера с помощью ключа
181                 'adapterNamespace' в массиве параметров.
182             </para>
184             <example id="zend.db.adapter.connecting.factory.example2">
185                 <title>Использование метода-фабрики для пользовательского класса адаптера</title>
186                 <programlisting language="php"><![CDATA[
187 // Нам не нужно загружать файл с классом адаптера,
188 // поскольку он будет загружен через метод-фабрику Zend_Db
190 // Автоматически загружает класс MyProject_Db_Adapter_Pdo_Mysql
191 // и создает его экземпляр.
192 $db = Zend_Db::factory('Pdo_Mysql', array(
193     'host'             => '127.0.0.1',
194     'username'         => 'webuser',
195     'password'         => 'xxxxxxxx',
196     'dbname'           => 'test',
197     'adapterNamespace' => 'MyProject_Db_Adapter'
200                 </programlisting>
201             </example>
203         </sect3>
205         <sect3 id="zend.db.adapter.connecting.factory-config">
207             <title>Использование Zend_Config с фабрикой Zend_Db</title>
209             <para>
210                 Опционально вы можете заменить оба аргумента метода
211                 <code>factory()</code> объектом типа
212                 <link linkend="zend.config">Zend_Config</link>.
213             </para>
215             <para>
216                 Если первым аргументом является объект конфигурации, то
217                 ожидается, что он имеет свойство с именем <code>adapter</code>,
218                 содержащее строку с базовой частью имени класса адаптера.
219                 Опционально объект может содержать свойство с именем
220                 <code>params</code> и "подсвойствами", соответствующими
221                 параметрам адаптера.
222             </para>
224             <example id="zend.db.adapter.connecting.factory.example1">
225                 <title>Использование метода-фабрики адаптеров с объектом Zend_Config</title>
226                 <para>
227                     В примере ниже объект Zend_Config создан из массива. Вы
228                     можете также загружать данные из внешнего файла с помощью
229                     <link linkend="zend.config.adapters.ini">Zend_Config_Ini</link>
230                     или <link linkend="zend.config.adapters.xml">Zend_Config_Xml</link>.
231                 </para>
232                 <programlisting language="php"><![CDATA[
233 $config = new Zend_Config(
234     array(
235         'database' => array(
236             'adapter' => 'Mysqli',
237             'params' => array(
238                 'dbname' => 'test',
239                 'username' => 'webuser',
240                 'password' => 'secret',
241             )
242         )
243     )
246 $db = Zend_Db::factory($config->database);
248                 </programlisting>
249             </example>
251             <para>
252                 Второй аргумент метода <code>factory()</code> может быть
253                 ассоциативным массивом, содержащим элементы, которые
254                 соответствуют параметрам адаптера. Этот аргумент является
255                 опциональным. Если первым аргументом является объект типа
256                 Zend_Config, то предполагается, что он содержит все необходимые
257                 параметры, и второй аргумент игнорируется.
258             </para>
260         </sect3>
262         <sect3 id="zend.db.adapter.connecting.parameters">
264             <title>Параметры адаптера</title>
266             <para>
267                 Список ниже описывает общие параметры, которые распознаются
268                 классами адаптеров Zend_Db.
269             </para>
271             <itemizedlist>
272                 <listitem>
273                     <para>
274                         <emphasis>host</emphasis>:
275                         строка, содержащая имя хоста или IP сервера БД. Если
276                         база данных размещается на том же хосте, что и
277                         приложение PHP, то вы можете использовать 'localhost'
278                         или '127.0.0.1'.
279                     </para>
280                 </listitem>
281                 <listitem>
282                     <para>
283                         <emphasis>username</emphasis>:
284                         идентификатор учетной записи для аутентификации подключения к серверу СУРБД.
285                     </para>
286                 </listitem>
287                 <listitem>
288                     <para>
289                         <emphasis>password</emphasis>:
290                         пароль  учетной записи для аутентификации подключения к
291                         серверу СУРБД.
292                     </para>
293                 </listitem>
294                 <listitem>
295                     <para>
296                         <emphasis>dbname</emphasis>:
297                         имя экземпляра БД на сервере СУРБД.
298                     </para>
299                 </listitem>
300                 <listitem>
301                     <para>
302                         <emphasis>port</emphasis>:
303                         некоторые сервера СУРБД поддерживают сетевые соединения
304                         через указанный администратором порт. Данный параметр
305                         дает возможность задать порт, с которым приложение PHP
306                         будет устанавливать соединение, он должен
307                         соответствовать порту, установленному в сервере СУРБД.
308                     </para>
309                 </listitem>
310                 <listitem>
311                     <para>
312                         <emphasis>options</emphasis>:
313                         этот параметр является ассоциативным массивом опций,
314                         общих для всех классов Zend_Db_Adapter.
315                     </para>
316                 </listitem>
317                 <listitem>
318                     <para>
319                         <emphasis>driver_options</emphasis>:
320                         этот параметр является ассоциативным массивом
321                         дополнительных опций, специфических для данного
322                         расширения. Одним из типичных случаев использования
323                         этого параметра является установка атрибутов для
324                         драйвера PDO.
325                     </para>
326                 </listitem>
327                 <listitem>
328                     <para>
329                         <emphasis>adapterNamespace</emphasis>:
330                         имя начальной части имени класса для адаптера вместо
331                         'Zend_Db_Adapter'. Используйте его, если нужно
332                         использовать метод <code>factory()</code> для загрузки
333                         "неZend'овского" класса адаптера БД.
334                     </para>
335                 </listitem>
336             </itemizedlist>
338             <example id="zend.db.adapter.connecting.parameters.example1">
339                 <title>Передача фабрике опции перевода регистра (case-folding)</title>
340                 <para>
341                     Вы можете установить эту опцию посредством константы
342                     <code>Zend_Db::CASE_FOLDING</code>. Она соответствует
343                     атрибуту <code>ATTR_CASE</code> в драйверах PDO и IBM DB2, и
344                     переводит строковые ключи в результатах запроса в требуемый
345                     регистр. Эта опция принимает значения
346                     <code>Zend_Db::CASE_NATURAL</code> (значение по умолчанию),
347                     <code>Zend_Db::CASE_UPPER</code> и
348                     <code>Zend_Db::CASE_LOWER</code>.
349                 </para>
350                 <programlisting language="php"><![CDATA[
351 $options = array(
352     Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
355 $params = array(
356     'host'           => '127.0.0.1',
357     'username'       => 'webuser',
358     'password'       => 'xxxxxxxx',
359     'dbname'         => 'test',
360     'options'        => $options
363 $db = Zend_Db::factory('Db2', $params);
365                 </programlisting>
366             </example>
368             <example id="zend.db.adapter.connecting.parameters.example2">
369                 <title>Передача фабрике опции автоматического заключения в кавычки</title>
370                 <para>
371                     Вы можете задавать эту опцию через константу
372                     <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>. Если ее
373                     значение установлено в <constant>TRUE</constant> (по умолчанию), то
374                     идентификаторы, такие, как имена таблиц, имена столбцов и
375                     даже псевдонимы, разграничиваются во всем генерируемом
376                     объектом адаптера синтаксисе SQL. Это делает возможным
377                     использование идентификаторов, содержащих ключевые слова SQL
378                     и специальные символы. Если его значение равно
379                     <constant>FALSE</constant>, то автоматическое заключение в кавычки
380                     не производится. Если требуется заключение идентификаторов в
381                     кавычки, то оно должно производиться самостоятельно с
382                     использованием метода <code>quoteIdentifier()</code>.
383                 </para>
384                 <programlisting language="php"><![CDATA[
385 $options = array(
386     Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
389 $params = array(
390     'host'           => '127.0.0.1',
391     'username'       => 'webuser',
392     'password'       => 'xxxxxxxx',
393     'dbname'         => 'test',
394     'options'        => $options
397 $db = Zend_Db::factory('Pdo_Mysql', $params);
399                 </programlisting>
400             </example>
402             <example id="zend.db.adapter.connecting.parameters.example3">
403                 <title>Передача фабрике опций драйвера PDO</title>
404                 <programlisting language="php"><![CDATA[
405 $pdoParams = array(
406     PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
409 $params = array(
410     'host'           => '127.0.0.1',
411     'username'       => 'webuser',
412     'password'       => 'xxxxxxxx',
413     'dbname'         => 'test',
414     'driver_options' => $pdoParams
417 $db = Zend_Db::factory('Pdo_Mysql', $params);
419 echo $db->getConnection()
420         ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
422                 </programlisting>
423             </example>
425         </sect3>
427         <sect3 id="zend.db.adapter.connecting.getconnection">
428             <title>Управление отложенными соединениями</title>
430             <para>
431                 Создание экземпляра класса адаптера не приведет к немедленному
432                 соединению с сервером СУРБД. Адаптер сохраняет параметры
433                 соединения и производит подключение, когда нужно произвести
434                 первый запрос к БД. Это значит, что само по себе создание
435                 объекта адаптера производится быстро и занимает мало ресурсов.
436                 Вы можете создавать экземпляр адаптера даже в том случае, если
437                 не уверены в том, что текущий запрос к вашему приложению
438                 требует каких-либо действий с БД.
439             </para>
441             <para>
442                 Если нужно принудительно создать соединение с СУРБД, то
443                 используйте метод <code>getConnection()</code>. Этот метод
444                 возвращает объект соединения в представлении соответствующего
445                 расширения PHP для баз данных. Например, если вы используете
446                 какой-либо класс адаптера для драйверов PDO, то
447                 <code>getConnection()</code> возвращает объект PDO после того,
448                 как он будет инициирован им в качестве "живого" соединения с
449                 определенной БД.
450             </para>
452             <para>
453                 Принудительное создание соединения может быть полезным, когда вы
454                 хотите отлавливать все исключения, которые бросаются из-за
455                 неправильных параметров доступа или других ошибок соединения с
456                 сервером СУРБД. Эти исключения не бросаются до тех пор, пока не
457                 создается соединение, поэтому можно упростить
458                 код приложения, обрабатывая исключения в одном
459                 месте вместо того, чтобы делать это каждый раз, когда
460                 производится первый запрос к БД.
461             </para>
463             <example id="zend.db.adapter.connecting.getconnection.example">
464                 <title>Обработка исключений при соединении</title>
465                 <programlisting language="php"><![CDATA[
466 try {
467     $db = Zend_Db::factory('Pdo_Mysql', $parameters);
468     $db->getConnection();
469 } catch (Zend_Db_Adapter_Exception $e) {
470     // возможно, неправильные параметры соединения или СУРБД не запущена
471 } catch (Zend_Exception $e) {
472     // возможно, попытка загрузки требуемого класса адаптера потерпела неудачу
475                 </programlisting>
476             </example>
478         </sect3>
480     </sect2>
482     <sect2 id="zend.db.adapter.example-database">
484         <title>Пример базы данных</title>
486         <para>
487             В документации к классам Zend_Db мы использовали набор простых
488             таблиц для того, чтобы проиллюстрировать использование классов и их
489             методов. Эти таблицы должны были хранить информацию для отслеживания
490             ошибок в проекте разработки ПО. База данных содержит четыре таблицы:
491         </para>
493         <itemizedlist>
494             <listitem>
495                 <para>
496                     <emphasis>accounts</emphasis> (учетные записи)
497                     хранит информацию о всех пользователях системы отслеживания
498                     ошибок.
499                 </para>
500             </listitem>
501             <listitem>
502                 <para>
503                     <emphasis>products</emphasis> (продукты)
504                     хранит информацию обо всех программных продуктах, для
505                     которых могут отслеживаться ошибки.
506                 </para>
507             </listitem>
508             <listitem>
509                 <para>
510                     <emphasis>bugs</emphasis> (ошибки) хранит
511                     информацию об ошибках, включая текущее состояние ошибки,
512                     лицо, сообщившее об ошибке, лицо, которому назначено
513                     устранение ошибки и лицо, которому назначена проверка
514                     устранения ошибки.
515                 </para>
516             </listitem>
517             <listitem>
518                 <para>
519                     <emphasis>bugs_products</emphasis> хранит
520                     связи между ошибками и продуктами. Она реализует связь
521                     "многие-ко-многим", потому что одна ошибка может относиться
522                     к нескольким продуктам, и один продукт может иметь множество
523                     ошибок.
524                 </para>
525             </listitem>
526         </itemizedlist>
528         <para>
529             Следующий псевдокод для определения данных SQL описывает таблицы в
530             этой базе данных. Это таблицы интенсивно используются в unit-тестах
531             для Zend_Db.
532         </para>
534         <programlisting language="sql"><![CDATA[
535 CREATE TABLE accounts (
536   account_name      VARCHAR(100) NOT NULL PRIMARY KEY
539 CREATE TABLE products (
540   product_id        INTEGER NOT NULL PRIMARY KEY,
541   product_name      VARCHAR(100)
544 CREATE TABLE bugs (
545   bug_id            INTEGER NOT NULL PRIMARY KEY,
546   bug_description   VARCHAR(100),
547   bug_status        VARCHAR(20),
548   reported_by       VARCHAR(100) REFERENCES accounts(account_name),
549   assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
550   verified_by       VARCHAR(100) REFERENCES accounts(account_name)
553 CREATE TABLE bugs_products (
554   bug_id            INTEGER NOT NULL REFERENCES bugs,
555   product_id        INTEGER NOT NULL REFERENCES products,
556   PRIMARY KEY       (bug_id, product_id)
559         </programlisting>
561         <para>
562             Также обратите внимание, что таблица <code>bugs</code> содержит
563             несколько внешних ключей, ссылающихся на таблицу
564             <code>accounts</code>. Для одной ошибки эти внешние ключи могут
565             ссылаться на разные строки в таблице <code>accounts</code>.
566         </para>
568         <para>
569             Диаграмма ниже иллюстрирует физическую модель данных для этой базы
570             данных.
571         </para>
573         <para>
574             <inlinegraphic width="387" scale="100" align="center" valign="middle"
575                 fileref="figures/zend.db.adapter.example-database.png" format="PNG" />
576         </para>
578     </sect2>
580     <sect2 id="zend.db.adapter.select">
582         <title>Чтение результатов запроса</title>
584         <para>
585             Этот раздел описывает методы класса адаптера, с помощью которых вы
586             можете производить запросы SELECT и извлекать их результаты.
587         </para>
589         <sect3 id="zend.db.adapter.select.fetchall">
591             <title>Извлечение полного набора результатов</title>
593             <para>
594                 Вы можете запустить запрос SELECT и извлечь его результаты за
595                 один шаг, используя метод <code>fetchAll()</code>.
596             </para>
598             <para>
599                 Первым аргументом этого метода должна быть строка, содержащая
600                 оператор SELECT. Также первым аргументом может быть объект
601                 класса <link linkend="zend.db.select">Zend_Db_Select</link>.
602                 Адаптер автоматически преобразует этот объект в строковое
603                 представление оператора SELECT.
604             </para>
606             <para>
607                 Вторым аргументом <code>fetchAll()</code> должен быть массив
608                 значений для подстановки вместо меток заполнения (placeholders)
609                 в операторе SQL.
610             </para>
612             <example id="zend.db.adapter.select.fetchall.example">
613                 <title>Использование fetchAll()</title>
614                 <programlisting language="php"><![CDATA[
615 $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
617 $result = $db->fetchAll($sql, 2);
619                 </programlisting>
620             </example>
622         </sect3>
624         <sect3 id="zend.db.adapter.select.fetch-mode">
626             <title>Изменение режима извлечения</title>
628             <para>
629                 По умолчанию <code>fetchAll()</code> возвращает массив строк,
630                 каждая из которых представлена ассоциативным
631                 массивом. Ключами ассоциативных массивов являются имена столбцов
632                 или псевдонимы столбцов, определенные в данном запросе на
633                 выборку.
634             </para>
636             <para>
637                 Вы можете задать другой стиль извлечения результатов, используя
638                 метод <code>setFetchMode()</code>. Поддерживаемые режимы
639                 идентифицируются константами:
640             </para>
642             <itemizedlist>
643                 <listitem>
644                     <para>
645                         <emphasis>Zend_Db::FETCH_ASSOC</emphasis>:
646                         возвращает данные в массиве ассоциативных массивов.
647                         Ключами массива являются имена столбцов в виде строк.
648                         Это режим извлечения, используемый по умолчанию в
649                         классах Zend_Db_Adapter.
650                     </para>
651                     <para>
652                         Обратите внимание, что если ваш список выборки содержит
653                         столбцы с одинаковыми именами, например, если они из
654                         разных таблиц в JOIN-е, то в ассоциативном массиве может
655                         быть только одна запись для этого имени. Если вы
656                         используете режим FETCH_ASSOC, то должны задавать
657                         псевдонимы столбцов в своем запросе SELECT для того,
658                         чтобы для всех столбцов были свои уникальные ключи.
659                     </para>
660                     <para>
661                         По умолчанию эти строки возвращаются так же, как если бы
662                         они были возвращены драйвером БД. Как правило, это
663                         синтаксис столбцов для данного сервера СУРБД. Вы можете
664                         задать регистр для этих строк, используя опцию.
665                         <code>Zend_Db::CASE_FOLDING</code>. Задавайте его во
666                         время инстанцирования адаптера. См.
667                         <xref linkend="zend.db.adapter.connecting.parameters.example1" />.
668                     </para>
669                 </listitem>
670                 <listitem>
671                     <para>
672                         <emphasis>Zend_Db::FETCH_NUM</emphasis>:
673                         возвращает данные в массиве массивов. Массив
674                         индексируется целочисленными значениями в соответствии с
675                         позицией данного поля в списке выборки запроса.
676                     </para>
677                 </listitem>
678                 <listitem>
679                     <para>
680                         <emphasis>Zend_Db::FETCH_BOTH</emphasis>:
681                         возвращает данные в массиве массивов. Ключами массива
682                         являются как строки, так и целочисленные значения. Число
683                         элементов в массиве получается в два раза больше, чем
684                         если бы использовались FETCH_ASSOC или FETCH_NUM.
685                     </para>
686                 </listitem>
687                 <listitem>
688                     <para>
689                         <emphasis>Zend_Db::FETCH_COLUMN</emphasis>:
690                         возвращает данные в массиве значений. Значение в каждом
691                         массиве является значением, возвращенным из одного
692                         столбца результата выборки. По умолчанию это первый
693                         столбец, индексированный нулем.
694                     </para>
695                 </listitem>
696                 <listitem>
697                     <para>
698                         <emphasis>Zend_Db::FETCH_OBJ</emphasis>:
699                         возвращает данные в массиве объектов. По умолчанию
700                         используется встроенный в PHP класс stdClass. Столбцы
701                         результата выборки доступны в качестве открытых свойств
702                         этого объекта.
703                     </para>
704                 </listitem>
705             </itemizedlist>
707             <example id="zend.db.adapter.select.fetch-mode.example">
708                 <title>Использование setFetchMode()</title>
709                 <programlisting language="php"><![CDATA[
710 $db->setFetchMode(Zend_Db::FETCH_OBJ);
712 $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
714 // $result является массивом объектов
715 echo $result[0]->bug_description;
717                 </programlisting>
718             </example>
720         </sect3>
722         <sect3 id="zend.db.adapter.select.fetchassoc">
724             <title>Извлечение результатов выборки в виде ассоциативного массива</title>
726             <para>
727                 Метод <code>fetchAssoc()</code> возвращает данные в массиве
728                 ассоциативных массивов безотносительно того, какое значение вы
729                 установили для режима извлечения.
730             </para>
732             <example id="zend.db.adapter.select.fetchassoc.example">
733                 <title>Использование fetchAssoc()</title>
734                 <programlisting language="php"><![CDATA[
735 $db->setFetchMode(Zend_Db::FETCH_OBJ);
737 $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
739 // $result является массивом ассоциативных массивов, независимо
740 // от установленного режима извлечения
741 echo $result[0]['bug_description'];
743                 </programlisting>
744             </example>
746         </sect3>
748         <sect3 id="zend.db.adapter.select.fetchcol">
750             <title>Извлечение единственного столбца из результатов выборки</title>
752             <para>
753                 Метод <code>fetchCol()</code> возвращает данные в массиве
754                 значений безотносительно того, какое значение вы
755                 установили для режима извлечения. Он возвращает только первый
756                 столбец из возвращенных запросом. Все остальные столбцы,
757                 возвращенные запросом, не учитываются. Если вам нужно извлечь
758                 столбец, отличный от первого, то см.
759                 <xref linkend="zend.db.statement.fetching.fetchcolumn" />.
760             </para>
762             <example id="zend.db.adapter.select.fetchcol.example">
763                 <title>Использование fetchCol()</title>
764                 <programlisting language="php"><![CDATA[
765 $db->setFetchMode(Zend_Db::FETCH_OBJ);
767 $result = $db->fetchCol(
768     'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
770 // содержит bug_description; bug_id не возвращается
771 echo $result[0];
773                 </programlisting>
774             </example>
776         </sect3>
778         <sect3 id="zend.db.adapter.select.fetchpairs">
780             <title>Извлечение пар ключ-значение из результатов выборки</title>
782             <para>
783                 Метод <code>fetchPairs()</code> возвращает данные в массиве пар
784                 ключ-значение,
785                 Ключ ассоциативного массива берется из первого столбца,
786                 возвращенного запросом SELECT. Значение берется из второго
787                 столбца, возвращенного запросом SELECT. Все остальные столбцы,
788                 возвращенные запросом, не учитываются.
789             </para>
791             <para>
792                 Вы должны строить запрос SELECT так, чтобы первый из
793                 возвращенных столбцов имел уникальные значения. Если в нем
794                 имеются повторяющиеся значения, то записи в ассоциативном
795                 массиве будут перезаписываться.
796             </para>
798             <example id="zend.db.adapter.select.fetchpairs.example">
799                 <title>Использование fetchPairs()</title>
800                 <programlisting language="php"><![CDATA[
801 $db->setFetchMode(Zend_Db::FETCH_OBJ);
803 $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
805 echo $result[2];
807                 </programlisting>
808             </example>
809         </sect3>
811         <sect3 id="zend.db.adapter.select.fetchrow">
813             <title>Извлечение единственной строки из результатов выборки</title>
815             <para>
816                 Метод <code>fetchRow()</code> возвращает данные с использованием
817                 текущего режима извлечения, но возвращает только первую строку
818                 из результатов выборки.
819             </para>
821             <example id="zend.db.adapter.select.fetchrow.example">
822                 <title>Использование fetchRow()</title>
823                 <programlisting language="php"><![CDATA[
824 $db->setFetchMode(Zend_Db::FETCH_OBJ);
826 $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
828 // обратите внимание, что $result - единственный объект, а не массив объектов
829 echo $result->bug_description;
831                 </programlisting>
832             </example>
833         </sect3>
835         <sect3 id="zend.db.adapter.select.fetchone">
837             <title>Извлечение единственного скалярного значения из результатов выборки</title>
839             <para>
840                 Метод <code>fetchOne()</code> является как бы комбинацией
841                 методов <code>fetchRow()</code> и <code>fetchCol()</code> - он
842                 возвращает значение первого столбца в первой строке из
843                 результатов выборки. Таким образом, он возвращает одно скалярное
844                 значение, а не массив или объект.
845             </para>
847             <example id="zend.db.adapter.select.fetchone.example">
848                 <title>Использование fetchOne()</title>
849                 <programlisting language="php"><![CDATA[
850 $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
852 // это единственное строковое значение
853 echo $result;
855                 </programlisting>
856             </example>
857         </sect3>
859     </sect2>
861     <sect2 id="zend.db.adapter.write">
863         <title>Изменение данных в БД</title>
865         <para>
866             Вы можете использовать класс адаптера для добавления новых данных
867             или изменения существующих в своей базе данных. В данном разделе
868             описываются методы для произведения этих операций.
869         </para>
871         <sect3 id="zend.db.adapter.write.insert">
873             <title>Добавление данных</title>
875             <para>
876                 Вы можете добавлять новые строки в таблицы в своей базе данных,
877                 используя метод  <code>insert()</code>. Первым аргументом этого
878                 метода является строка с именем таблицы, а вторым аргументом -
879                 ассоциативный массив с именами столбцов и соответствующими им
880                 значениями.
881             </para>
883             <example id="zend.db.adapter.write.insert.example">
884                 <title>Добавление в таблицу</title>
885                 <programlisting language="php"><![CDATA[
886 $data = array(
887     'created_on'      => '2007-03-22',
888     'bug_description' => 'Something wrong',
889     'bug_status'      => 'NEW'
892 $db->insert('bugs', $data);
894                 </programlisting>
895             </example>
897             <para>
898                 Те столбцы, которые не были включены в массив данных, не
899                 передаются базе данных. Таким образом, они следуют тем же
900                 правилам, что и SQL-оператор INSERT: если столбец имеет
901                 предложение DEFAULT, то он принимает это значение в созданной
902                 строке, иначе остается в состоянии NULL.
903             </para>
905             <para>
906                 По умолчанию значения в вашем массиве данных добавляются с
907                 использованием параметров. Это сокращает некоторые риски
908                 безопасности. Вам не нужно будет применять к значениям в массиве
909                 данных такие действия, как взятие в кавычки или экранирование.
910             </para>
912             <para>
913                 Иногда бывает необходимо, чтобы часть значений в массиве данных
914                 трактовалась как SQL-выражения, в этом случае они не должны
915                 заключаться в кавычки. По умолчанию все данные, переданные в
916                 виде строк, трактуются как строковые литералы. Для того, чтобы
917                 указать, что данное значение является SQL-выражением (а
918                 значит, не должно заключаться в кавычки), передавайте его в
919                 массиве данных в виде объекта типа Zend_Db_Expr вместо простой
920                 строки.
921             </para>
923             <example id="zend.db.adapter.write.insert.example2">
924                 <title>Добавление выражений в таблицу</title>
925                 <programlisting language="php"><![CDATA[
926 $data = array(
927     'created_on'      => new Zend_Db_Expr('CURDATE()'),
928     'bug_description' => 'Something wrong',
929     'bug_status'      => 'NEW'
932 $db->insert('bugs', $data);
934                 </programlisting>
935             </example>
937         </sect3>
939         <sect3 id="zend.db.adapter.write.lastinsertid">
941             <title>Получение сгенерированного значения</title>
943             <para>
944                 Некоторые СУРБД поддерживают автоинкремент первичных ключей.
945                 Таблица, описанная определенным образом, автоматически
946                 генерирует значение первичного ключа во время добавления новой
947                 строки.
948                 Возвращаемое методом <code>insert()</code> значение
949                 <emphasis>не</emphasis> является последним добавленным
950                 идентификатором, потому что таблица может не иметь
951                 автоинкрементных столбцов. Вместо этого возвращаемое
952                 значение является количеством затронутых строк (обычно 1).
953             </para>
955             <para>
956                 Если ваша таблица определена с автоинкрементным первичным
957                 ключом, то вы можете вызывать метод <code>lastInsertId()</code>
958                 после добавления. Этот метод возвращает последнее значение,
959                 сгенерированное в области видимости текущего соединения с БД.
960             </para>
962             <example id="zend.db.adapter.write.lastinsertid.example-1">
963                 <title>Использование lastInsertId() для автоинкрементного ключа</title>
964                 <programlisting language="php"><![CDATA[
965 $db->insert('bugs', $data);
967 // возвращает последнее значение, сгенерированное автоинкрементным столбцом
968 $id = $db->lastInsertId();
970                 </programlisting>
971             </example>
973             <para>
974                 Некоторые СУРБД поддерживают объекты последовательностей
975                 (sequence object), которые генерируют уникальные значения для
976                 использования в качестве значений первичных ключей. Для
977                 поддержки последовательностей <code>lastInsertId()</code>
978                 принимает два необязательных строковых аргумента. Эти аргументы
979                 служат для передачи имен таблицы и столбца, при этом
980                 предполагается, что вы следуете соглашению, по которому имя
981                 последовательности состоит из имен таблицы и столбца, для
982                 которых эта последовательность генерирует значения, и суффикса
983                 "_seq". Это соглашение основано на используемом системой
984                 PostgreSQL при именовании последовательностей для столбцов
985                 SERIAL. Например, таблица "bugs" с первичным ключом "bug_id"
986                 должна использовать последовательность с именем
987                 "bugs_bug_id_seq".
988             </para>
990             <example id="zend.db.adapter.write.lastinsertid.example-2">
991                 <title>Использование lastInsertId() для последовательности</title>
992                 <programlisting language="php"><![CDATA[
993 $db->insert('bugs', $data);
995 // возвращает последнее значение, сгенерированное
996 // последовательностью 'bugs_bug_id_seq'
997 $id = $db->lastInsertId('bugs', 'bug_id');
999 // альтернативно, возвращает последнее значение, сгенерированное
1000 // последовательностью 'bugs_seq'.
1001 $id = $db->lastInsertId('bugs');
1003                 </programlisting>
1004             </example>
1006             <para>
1007                 Если имя вашего объекта последовательности не следует этому
1008                 соглашению по именованию, то используйте метод
1009                 <code>lastSequenceId()</code>. Этот метод принимает один
1010                 строковой аргумент, через который передается точное имя
1011                 последовательности
1012             </para>
1014             <example id="zend.db.adapter.write.lastinsertid.example-3">
1015                 <title>Использование lastSequenceId()</title>
1016                 <programlisting language="php"><![CDATA[
1017 $db->insert('bugs', $data);
1019 // возвращает последнее значение, сгенерированное
1020 // последовательностью 'bugs_id_gen'.
1021 $id = $db->lastSequenceId('bugs_id_gen');
1023                 </programlisting>
1024             </example>
1026             <para>
1027                 Для тех СУРБД, которые не поддерживают последовательности,
1028                 включая MySQL, Microsoft SQL Server и SQLite, аргументы метода
1029                 lastInsertId() игнорируются, и возвращается самое последнее
1030                 значение, сгенерированное для любой таблицы через оператор
1031                 INSERT в течение данного соединения. Для этих типов СУРБД метод
1032                 lastSequenceId() всегда будет возвращать <constant>NULL</constant>.
1033             </para>
1035             <note>
1036                 <title>Почему не используется "SELECT MAX(id) FROM table"?</title>
1037                 <para>
1038                     Иногда этот запрос возвращает последнее значение первичного
1039                     ключа, добавленное в таблицу. Однако этот способ небезопасен
1040                     в условиях, когда несколько клиентов добавляют записи в базу
1041                     данных. Может случиться (и должно происходить в конечном
1042                     итоге) так, что другой клиент добавляет другую строку в
1043                     короткий промежуток времени между добавлением строки,
1044                     производимым вашим приложением-клиентом БД, и вашим запросом
1045                     для получения значения MAX(id). Таким образом, это
1046                     возвращаемое значение не будет соответствовать добавленной
1047                     вами строке, вместо этого оно будет соответствовать строке,
1048                     добавленной другим клиентом. Нет способа определить,
1049                     когда это происходит.
1050                 </para>
1051                 <para>
1052                     Использование высокого уровня изоляции транзакций, такого,
1053                     как "repeatable read", может уменьшить этот риск, но
1054                     некоторые СУРБД не поддерживают требуемую для этого изоляцию
1055                     транзакций, либо намеренно используется более низкий уровень
1056                     изоляции транзакций в приложении.
1057                 </para>
1058                 <para>
1059                     Использование выражения наподобие "MAX(id)+1" для генерации
1060                     нового значения первичного ключа тоже небезопасно, так как
1061                     два клиента могут сделать этот запрос одновременно, и оба
1062                     будут использовать одно и то же полученное значение для
1063                     своей последующей операции INSERT.
1064                 </para>
1065                 <para>
1066                     Все СУРБД предоставляют механизмы для генерации уникальных
1067                     значений и возвращения последних сгенерированных значений.
1068                     Эти механизмы работают вне области видимости транзакций,
1069                     поэтому нет вероятности того, что оба клиента сгенерируют
1070                     одно и то же значение, или что значение, сгенерированное
1071                     другим клиентом, будет возвращено вашему клиенту как
1072                     последнее сгенерированное им в его соединении.
1073                 </para>
1074             </note>
1076         </sect3>
1078         <sect3 id="zend.db.adapter.write.update">
1079             <title>Обновление данных</title>
1081             <para>
1082                 Вы можете обновлять строки в таблице БД, используя метод
1083                 <code>update()</code> адаптера. Этот метод принимает три
1084                 аргумента: первый является имением таблицы, второй -
1085                 ассоциативным массивом столбцов, которые требуется изменить, и
1086                 значений, которые требуется присвоить этим столбцам.
1087             </para>
1089             <para>
1090                 Значения в массиве данных интерпретируются как строковые
1091                 константы. Информацию об использовании выражений SQL в массиве
1092                 данных см. в разделе
1093                 <xref linkend="zend.db.adapter.write.insert" />.
1094             </para>
1096             <para>
1097                 Третий аргумент является строкой, содержащей выражение SQL,
1098                 которое используется в качестве условия, при выполнении которого
1099                 строка должна изменяться. Значения и идентификаторы в этом
1100                 аргументе не заключаются в кавычки и не экранируются. Вы
1101                 ответственны за то, чтобы все динамическое содержимое было
1102                 безопасным образом включено в эту строку. Информацию о методах,
1103                 которые помогут вам в этом, см. в разделе
1104                 <xref linkend="zend.db.adapter.quoting" />.
1105             </para>
1107             <para>
1108                 Возвращаемое значение является числом строк, затронутых в
1109                 операции обновления.
1110             </para>
1112             <example id="zend.db.adapter.write.update.example">
1113                 <title>Обновление строк</title>
1114                 <programlisting language="php"><![CDATA[
1115 $data = array(
1116     'updated_on'      => '2007-03-23',
1117     'bug_status'      => 'FIXED'
1120 $n = $db->update('bugs', $data, 'bug_id = 2');
1122                 </programlisting>
1123             </example>
1125             <para>
1126                 Если вы опустите третий аргумент, то все строки в таблице БД
1127                 будут обновлены со значениями, указанными в массиве данных.
1128             </para>
1130             <para>
1131                 Если вы передадите массив строк в качестве третьего аргумента,
1132                 то эти строки будут объединены как термы выражения, разделенные
1133                 операторами <code>AND</code>.
1134             </para>
1136             <example id="zend.db.adapter.write.update.example-array">
1137                 <title>Обновление строк с использованием массива выражений</title>
1138                 <programlisting language="php"><![CDATA[
1139 $data = array(
1140     'updated_on'      => '2007-03-23',
1141     'bug_status'      => 'FIXED'
1144 $where[] = "reported_by = 'goofy'";
1145 $where[] = "bug_status = 'OPEN'";
1147 $n = $db->update('bugs', $data, $where);
1149 // Результирующий SQL:
1150 //  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
1151 //  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
1153                 </programlisting>
1154             </example>
1156         </sect3>
1158         <sect3 id="zend.db.adapter.write.delete">
1159             <title>Удаление данных</title>
1160             <para>
1161                 Вы можете удалять строки из таблицы БД, используя метод
1162                 <code>delete()</code>. Этот метод принимает два аргумента,
1163                 первый из них является строкой с именем таблицы.
1164             </para>
1166             <para>
1167                 Второй аргумент является строкой, содержащей выражение SQL,
1168                 который используется в качестве условия, при выполнении которого
1169                 строка удаляется. Значения и идентификаторы в этом аргументе не
1170                 заключаются в кавычки и не экранируются. Вы ответственны за то,
1171                 чтобы весь динамический контент был безопасным образом включен в
1172                 эту строку. Информацию о методах, которые помогут вам в этом,
1173                 см. в разделе <xref linkend="zend.db.adapter.quoting" />.
1174             </para>
1176             <para>
1177                 Возвращаемое значение является числом строк, задействованных в
1178                 операции удаления.
1179             </para>
1181             <example id="zend.db.adapter.write.delete.example">
1182                 <title>Удаление строк</title>
1183                 <programlisting language="php"><![CDATA[
1184 $n = $db->delete('bugs', 'bug_id = 3');
1186                 </programlisting>
1187             </example>
1189             <para>
1190                 Если вы опустите второй аргумент, то в результате
1191                 все строки в таблице БД будут удалены.
1192             </para>
1194             <para>
1195                 Если вы передадите массив строк в качестве второго аргумента, то
1196                 эти строки будут объединены как термы выражения, разделенные
1197                 операторами <code>AND</code>.
1198             </para>
1200         </sect3>
1202     </sect2>
1204     <sect2 id="zend.db.adapter.quoting">
1206         <title>Заключение в кавычки значений и идентификаторов</title>
1208         <para>
1209             При построении запросов SQL часто требуется включить значения
1210             переменных PHP в выражения SQL. Это несет в себе дополнительный
1211             риск, потому что если значение в строке PHP содержит определенные
1212             символы, такие, как символы кавычек, то в результате может
1213             получиться недопустимый код SQL. Например, обратите внимание на
1214             несоответствие кавычек в следующем запросе:
1215             <programlisting language="php"><![CDATA[
1216 $name = "O'Reilly";
1217 $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
1219 echo $sql;
1220 // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
1222             </programlisting>
1223         </para>
1225         <para>
1226             Еще серьезнее риск того, что такие ошибки в коде могут быть
1227             целенаправленно использованы тем, кто пытается получить управление
1228             вашим веб-приложением. Если он может указать значение переменной
1229             PHP, используя параметры HTTP или другой механизм, то может
1230             заставить ваши SQL-запросы выполнять действия, для которых они не
1231             предназначены - например, возвращение данных, на чтение которых лицо
1232             не имеет прав. Это серьезное и широко распространенное нарушение
1233             безопасности приложения, известное под названием "SQL-инъекции"
1234             (см. <ulink url="http://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%8A%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_SQL">http://ru.wikipedia.org/wiki/Инъекция_SQL</ulink>).
1235         </para>
1237         <para>
1238             Класс адаптера Zend_Db предоставляет удобные функции для того, чтобы
1239             уменьшить уязвимость приложения к SQL-инъекциям. Решение
1240             состоит в том, чтобы экранировать специальные символы, такие, как
1241             кавычки в значениях PHP, до того, как они будут включены в строки
1242             запросов SQL. Это защищает как от случайных, так и от
1243             целенаправленных манипуляций строками SQL через переменные PHP,
1244             содержащие специальные символы.
1245         </para>
1247         <sect3 id="zend.db.adapter.quoting.quote">
1249             <title>Использование <code>quote()</code></title>
1251             <para>
1252                 Метод <code>quote()</code> принимает единственный аргумент -
1253                 скалярное строковое значение. Он возвращает значение с
1254                 специальными символами, экранированными соответствующим образом
1255                 для используемой вами СУРБД, и окруженным ограничителями
1256                 строковых значений. Стандартным ограничителем строковых значений
1257                 в SQL является одинарная кавычка (<code>'</code>).
1258             </para>
1260             <example id="zend.db.adapter.quoting.quote.example">
1261                 <title>Использование quote()</title>
1262                 <programlisting language="php"><![CDATA[
1263 $name = $db->quote("O'Reilly");
1264 echo $name;
1265 // 'O\'Reilly'
1267 $sql = "SELECT * FROM bugs WHERE reported_by = $name";
1269 echo $sql;
1270 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1272                 </programlisting>
1273             </example>
1275             <para>
1276                 Обратите внимание, что возвращаемое методом <code>quote()</code>
1277                 значение включает в себя окружающие кавычки. Этим
1278                 метод отличается от некоторых функций, которые экранируют
1279                 специальные символы, но не добавляют кавычки, например,
1280                 <ulink url="http://www.php.net/mysqli_real_escape_string">mysql_real_escape_string()</ulink>.
1281             </para>
1283             <para>
1284                 Данные могут требовать или не требовать заключения в кавычки в
1285                 зависимости от того, в каком контексте типа данных SQL они
1286                 используются. Например, в некоторых СУРБД целочисленное
1287                 значение не должно заключаться в кавычки, если оно
1288                 сравнивается со столбцом или выражением целочисленного типа.
1289                 Другими словами, следующий запрос является ошибочным в некоторых
1290                 реализациях SQL, если столбец <code>intColumn</code> имеет
1291                 целочисленный тип данных <code>INTEGER</code>.
1293                 <programlisting language="php"><![CDATA[
1294 SELECT * FROM atable WHERE intColumn = '123'
1296                 </programlisting>
1297             </para>
1299             <para>
1300                 Вы можете использовать необязательный второй аргумент метода
1301                 <code>quote()</code> для избирательного заключения в кавычки
1302                 тех типов данных SQL, которые вы укажете.
1303             </para>
1305             <example id="zend.db.adapter.quoting.quote.example-2">
1306                 <title>Использование quote() с указанием типа SQL</title>
1307                 <programlisting language="php"><![CDATA[
1308 $value = '1234';
1309 $sql = 'SELECT * FROM atable WHERE intColumn = '
1310      . $db->quote($value, 'INTEGER');
1312                 </programlisting>
1313             </example>
1315             <para>
1316                 Каждый класс Zend_Db_Adapter имеет закодированные имена типов
1317                 данных SQL для соответствующих СУРБД. Вы можете также
1318                 использовать константы <code>Zend_Db::INT_TYPE</code>,
1319                 <code>Zend_Db::BIGINT_TYPE</code> и
1320                 <code>Zend_Db::FLOAT_TYPE</code> для написания еще более
1321                 независимого от типа используемой СУРБД кода.
1322             </para>
1324             <para>
1325                 Zend_Db_Table автоматически указывает типы SQL для метода
1326                 <code>quote()</code> при генерации SQL-запросов, ссылающихся на
1327                 ключевые столбцы таблицы.
1328             </para>
1330         </sect3>
1332         <sect3 id="zend.db.adapter.quoting.quote-into">
1334             <title>Использование <code>quoteInto()</code></title>
1336             <para>
1337                 Наиболее типичным случаем использования операции заключения в
1338                 кавычки является добавление переменной PHP в выражение или
1339                 оператор SQL. Вы можете использовать метод
1340                 <code>quoteInto()</code> для того, чтобы выполнить это за один
1341                 шаг. Этот метод принимает два аргумента: первый аргумент
1342                 является строкой, содержащей символ метки заполнения
1343                 (<code>?</code>), а второй аргумент - значением или
1344                 переменной PHP, которая должна быть подставлена вместо этой
1345                 метки заполнения.
1346             </para>
1348             <para>
1349                 Символ метки заполнения одинаковый в многих СУРБД для
1350                 позиционных параметров, но метод <code>quoteInto()</code> только
1351                 эмулирует параметры запроса. Этот метод просто добавляет
1352                 значение в строку, экранируя специальные символы и заключая его
1353                 в кавычки. В случае настоящих параметров запроса сохраняется
1354                 разделение между строкой SQL и параметрами, поскольку строка
1355                 запроса анализируется сервером СУРБД.
1356             </para>
1358             <example id="zend.db.adapter.quoting.quote-into.example">
1359                 <title>Использование quoteInto()</title>
1360                 <programlisting language="php"><![CDATA[
1361 $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
1363 echo $sql;
1364 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1366                 </programlisting>
1367             </example>
1369             <para>
1370                 Вы можете использовать опциональный третий параметр метода
1371                 <code>quoteInto()</code> для указания типа данных SQL. Числовые
1372                 типы данных не заключаются в кавычки, остальные заключаются.
1373             </para>
1375             <example id="zend.db.adapter.quoting.quote-into.example-2">
1376                 <title>Использование quoteInto() с указанием типа SQL</title>
1377                 <programlisting language="php"><![CDATA[
1378 $sql = $db->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
1380 echo $sql;
1381 // SELECT * FROM bugs WHERE reported_by = 1234
1383                 </programlisting>
1384             </example>
1386         </sect3>
1387         <sect3 id="zend.db.adapter.quoting.quote-identifier">
1389             <title>Использование <code>quoteIdentifier()</code></title>
1391             <para>
1392                 Значения являются не единственной частью синтаксиса SQL, которая
1393                 может изменяться. Если вы используете переменные PHP для имен
1394                 таблиц, столбцов и других идентификаторов в своих операторах
1395                 SQL, то эти строки тоже следует заключать в кавычки. По
1396                 умолчанию идентификаторы в SQL следуют тем же правилам
1397                 синтаксиса, что есть в PHP и других языках программирования.
1398                 Например, идентификаторы не должны содержать пробелы,
1399                 определенные знаки препинания, специальные символы или
1400                 международные символы. Также в синтаксисе SQL зарезервированы
1401                 некоторые слова, и они не должны использоваться в качестве
1402                 идентификаторов.
1403             </para>
1405             <para>
1406                 Тем не менее, в SQL есть возможность, которая называется
1407                 <emphasis>идентификаторы с ограничителями</emphasis> (delimited
1408                 identifiers), она дает б<emphasis>о</emphasis>льшие возможности
1409                 выбора идентификаторов. Если вы заключите идентификатор SQL в
1410                 кавычки требуемого типа, то можете использовать те
1411                 идентификаторы, которые были бы недопустимыми без кавычек.
1412                 Идентификаторы с ограничителями могут содержать пробелы, знаки
1413                 препинания и международные символы. Вы можете также использовать
1414                 зарезервированные слова SQL, если заключите их в ограничители
1415                 идентификаторов.
1416             </para>
1418             <para>
1419                 <code>quoteIdentifier()</code> работает так же, как
1420                 <code>quote()</code>, но он применяет символы ограничителей
1421                 идентификаторов к строке в соответствии с типом используемой
1422                 СУРБД. Например, стандартный SQL использует двойные кавычки
1423                 (<code>"</code>) в качестве ограничителей идентификаторов и
1424                 большинство типов СУРБД использует именно их. MySQL по умолчанию
1425                 использует обратные кавычки (<code>`</code>). Метод
1426                 <code>quoteIdentifier()</code> также экранирует специальные
1427                 символы в строковом аргументе.
1428             </para>
1430             <example id="zend.db.adapter.quoting.quote-identifier.example">
1431                 <title>Использование quoteIdentifier()</title>
1432                 <programlisting language="php"><![CDATA[
1433 // мы можем иметь имя таблицы,
1434 // которое является зарезервированным в SQL словом
1435 $tableName = $db->quoteIdentifier("order");
1437 $sql = "SELECT * FROM $tableName";
1439 echo $sql
1440 // SELECT * FROM "order"
1442                 </programlisting>
1443             </example>
1445             <para>
1446                 Идентификаторы с ограничителями в SQL являются чувствительными к
1447                 регистру, в отличие от не заключенных в кавычки. Поэтому, если
1448                 вы используете идентификаторы с ограничителями, то должны
1449                 использовать в точности то же написание идентификаторов, как и в
1450                 схеме БД, включая регистр букв.
1451             </para>
1453             <para>
1454                 В большинстве случаев, когда SQL генерируется в классах Zend_Db,
1455                 все идентификаторы по умолчанию автоматически заключаются в
1456                 ограничители. Вы можете изменить это поведение с помощью опции
1457                 <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>. Указывайте ее при
1458                 инстанцировании объекта адаптера. См.
1459                 <xref linkend="zend.db.adapter.connecting.parameters.example2" />.
1460             </para>
1462         </sect3>
1464     </sect2>
1466     <sect2 id="zend.db.adapter.transactions">
1468         <title>Управление транзакциями</title>
1470         <para>
1471             Базы данных описывают транзакции как логические единицы работы,
1472             которые могут фиксироваться или откатываться как одно изменение,
1473             даже если они затрагивают несколько таблиц. Все запросы к БД
1474             выполняются в контексте транзакций, даже если драйвер баз данных
1475             работает с ними неявным образом. Это называется режимом
1476             <emphasis>автоматической фиксации</emphasis>, в котором драйвера БД
1477             создают транзакции для каждого выполняемого SQL-оператора. По
1478             умолчанию все классы адаптеров Zend_Db функционируют в режиме
1479             автоматической фиксации.
1480         </para>
1482         <para>
1483             Вы можете также задавать начало и конец транзакции, и таким образом
1484             контролировать число SQL-запросов в группе, которая фиксируется (или
1485             откатывается) как одна операция.
1486             Используйте метод <code>beginTransaction()</code> для инициирования
1487             транзакции. Последующие SQL-операторы будут выполняться в контексте
1488             этой транзакции до тех пор, пока вы не завершите ее явным образом.
1489         </para>
1491         <para>
1492             Для завершения транзакции используйте методы <code>commit()</code>
1493             или <code>rollBack()</code>. Метод <code>commit()</code> помечает
1494             изменения, произведенные в течение данной транзакции, как
1495             зафиксированные, это означает, что результаты этих изменений будут
1496             видны в запросах, выполняемых в других транзакциях.
1497         </para>
1499         <para>
1500             Метод <code>rollBack()</code> делает обратное - он не учитывает
1501             изменения, произведенные в течение транзакции. Изменения будут
1502             эффективно отменены, и состояние данных вернется к тому, в котором
1503             они были до того, как была начата транзакция. Тем не менее, откат
1504             транзакции не повлияет на изменения, произведенные другими
1505             транзакциями, запущенными в это же время.
1506         </para>
1508         <para>
1509             После того, как вы завершите транзакцию,
1510             <code>Zend_Db_Adapter</code> вернется в режим автоматической
1511             фиксации до того, как вы не вызовете <code>beginTransaction()</code> снова.
1512         </para>
1514         <example id="zend.db.adapter.transactions.example">
1515             <title>Управление транзакциями для обеспечения согласованности данных</title>
1516             <programlisting language="php"><![CDATA[
1517 // Старт транзакции явным образом
1518 $db->beginTransaction();
1520 try {
1521     // Попытка произвести один или несколько запросов
1522     $db->query(...);
1523     $db->query(...);
1524     $db->query(...);
1526     // Если все запросы были произведены успешно, то транзакция фиксируется,
1527     // и все изменения фиксируются одновременно
1528     $db->commit();
1530 } catch (Exception $e) {
1531     // Если какой-либо из этих запросов прошел неудачно, то вся транзакция
1532     // откатывается, при этом все изменения отменяются, даже те, которые были
1533     // произведены успешно.
1534     // Таким образом, все изменения либо фиксируются, либо не фиксируется вместе.
1535     $db->rollBack();
1536     echo $e->getMessage();
1539             </programlisting>
1540         </example>
1542     </sect2>
1544     <sect2 id="zend.db.adapter.list-describe">
1546         <title>Листинг и описание таблиц</title>
1548         <para>
1549             Метод <code>listTables()</code> возвращает массив имен всех
1550             таблиц в текущей базе данных.
1551         </para>
1553         <para>
1554             Метод <code>describeTable()</code> возвращает ассоциативный массив
1555             метаданных таблицы. Указывайте имя таблицы в качестве первого
1556             аргумента этого метода. Второй аргумент является опциональным, и
1557             обозначает схему, в которой существует эта таблица.
1558         </para>
1560         <para>
1561             Ключами возвращаемого ассоциативного массива являются имена столбцов
1562             таблицы. Значения, соответствующие этим столбцам, также являются
1563             ассоциативными массивами со следующими ключами и значениями:
1564         </para>
1566         <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
1567             <title>Поля метаданных, возвращаемых методом describeTable()</title>
1568             <tgroup cols="3" align="left" colsep="1" rowsep="1">
1569                 <thead>
1570                     <row>
1571                         <entry>Ключ</entry>
1572                         <entry>Тип</entry>
1573                         <entry>Описание</entry>
1574                     </row>
1575                 </thead>
1576                 <tbody>
1577                     <row>
1578                         <entry>SCHEMA_NAME</entry>
1579                         <entry>(string)</entry>
1580                         <entry>Имя схемы БД, в которой находится эта таблица.</entry>
1581                     </row>
1582                     <row>
1583                         <entry>TABLE_NAME</entry>
1584                         <entry>(string)</entry>
1585                         <entry>Имя таблицы, которой принадлежит данный столбец.</entry>
1586                     </row>
1587                     <row>
1588                         <entry>COLUMN_NAME</entry>
1589                         <entry>(string)</entry>
1590                         <entry>Имя столбца</entry>
1591                     </row>
1592                     <row>
1593                         <entry>COLUMN_POSITION</entry>
1594                         <entry>(integer)</entry>
1595                         <entry>Порядковый номер столбца в таблице.</entry>
1596                     </row>
1597                     <row>
1598                         <entry>DATA_TYPE</entry>
1599                         <entry>(string)</entry>
1600                         <entry>Имя типа данных столбца, используемое в данной СУРБД</entry>
1601                     </row>
1602                     <row>
1603                         <entry>DEFAULT</entry>
1604                         <entry>(string)</entry>
1605                         <entry>Значение по умолчанию, если есть.</entry>
1606                     </row>
1607                     <row>
1608                         <entry>NULLABLE</entry>
1609                         <entry>(boolean)</entry>
1610                         <entry>TRUE, если столбец допускает значение NULL, иначе FALSE.</entry>
1611                     </row>
1612                     <row>
1613                         <entry>LENGTH</entry>
1614                         <entry>(integer)</entry>
1615                         <entry>Длина или значение столбца, сообщаемое СУРБД.</entry>
1616                     </row>
1617                     <row>
1618                         <entry>SCALE</entry>
1619                         <entry>(integer)</entry>
1620                         <entry>Масштаб для типа данных NUMERIC или DECIMAL.</entry>
1621                     </row>
1622                     <row>
1623                         <entry>PRECISION</entry>
1624                         <entry>(integer)</entry>
1625                         <entry>Точность для типа данных NUMERIC или DECIMAL.</entry>
1626                     </row>
1627                     <row>
1628                         <entry>UNSIGNED</entry>
1629                         <entry>(boolean)</entry>
1630                         <entry>TRUE, если целочисленный тип объявлен как UNSIGNED (беззнаковое число).</entry>
1631                     </row>
1632                     <row>
1633                         <entry>PRIMARY</entry>
1634                         <entry>(boolean)</entry>
1635                         <entry>TRUE, если столбец является частью первичного ключа этой таблицы.</entry>
1636                     </row>
1637                     <row>
1638                         <entry>PRIMARY_POSITION</entry>
1639                         <entry>(integer)</entry>
1640                         <entry>Порядковый номер (начинается с 1) данного столбца в первичном ключе.</entry>
1641                     </row>
1642                     <row>
1643                         <entry>IDENTITY</entry>
1644                         <entry>(boolean)</entry>
1645                         <entry>TRUE, если данный столбец использует автоматически генерируемые значения.</entry>
1646                     </row>
1647                 </tbody>
1648             </tgroup>
1649         </table>
1651         <para>
1652             Если таблица, соответствующая заданным имени таблицы и имени схемы
1653             (опционально), не существует, то <code>describeTable()</code>
1654             возвращает пустой массив.
1655         </para>
1657         <note>
1658             <title>Как поле метаданных IDENTITY соотносится с типом СУРБД</title>
1659             <para>
1660                 Поле метаданных IDENTITY было выбрано в качестве
1661                 "идиоматического" термина для представления связи с
1662                 суррогатными ключами. Это поле обычно знакомо под следующими
1663                 именами:
1664             </para>
1665             <itemizedlist>
1666                 <listitem>
1667                     <para>
1668                         <code>IDENTITY</code> - DB2, MSSQL
1669                     </para>
1670                 </listitem>
1671                 <listitem>
1672                     <para>
1673                         <code>AUTO_INCREMENT</code> - MySQL
1674                     </para>
1675                 </listitem>
1676                 <listitem>
1677                     <para>
1678                         <code>SERIAL</code> - PostgreSQL
1679                     </para>
1680                 </listitem>
1681                 <listitem>
1682                     <para>
1683                         <code>SEQUENCE</code> - Oracle
1684                     </para>
1685                 </listitem>
1686             </itemizedlist>
1687         </note>
1689     </sect2>
1691     <sect2 id="zend.db.adapter.closing">
1693         <title>Закрытие соединения</title>
1695         <para>
1696             Обычно нет необходимости в том, чтобы закрывать соединение с БД.
1697             PHP автоматически очищает все ресурсы в конце запроса. Расширения
1698             PHP для баз данных спроектированы таким образом, чтобы они закрывали
1699             соединение, когда удаляется ссылка на объект ресурса.
1700         </para>
1702         <para>
1703             Тем не менее, если у вас есть скрипт PHP длительного времени
1704             выполнения, который инициирует множество соединений с БД, то может
1705             потребоваться закрывать соединения, чтобы избежать снижения
1706             производительности сервера СУРБД. Вы можете использовать метод
1707             адаптера <code>closeConnection()</code> для явного закрытия лежащего
1708             в основе соединения с БД.
1709         </para>
1711         <example id="zend.db.adapter.closing.example">
1712             <title>Закрытие соединения с БД</title>
1713             <programlisting language="php"><![CDATA[
1714 $db->closeConnection();
1716             </programlisting>
1717         </example>
1719         <note>
1720             <title>Поддерживает ли Zend_Db постоянные соединения?</title>
1721             <para>
1722                 Использование постоянных соединений не поддерживается или
1723                 рекомендуется в Zend_Db.
1724             </para>
1725             <para>
1726                 Использование постоянных соединений может привести к избытку
1727                 неиспользуемых соединений на сервере СУРБД, что приносит больше
1728                 проблем, чем дает выигрыша в производительности, достигаемого
1729                 путем уменьшения накладных расходов на установку соединений.
1730             </para>
1731             <para>
1732                 Соединения с БД имеют свое состояние, т.е. некоторые объекты на
1733                 сервере СУРБД существуют в области видимости сессии. Примером
1734                 являются блокировки, пользовательские переменные, временные
1735                 таблицы и информация о последних выполненных запросах, такая,
1736                 как количество затронутых строк и последнее сгенерированное
1737                 значение. Если вы используете постоянные соединения, то ваше
1738                 приложение может получать неверные или привилегированные данные,
1739                 созданные в предыдущем PHP-запросе.
1740             </para>
1741         </note>
1743     </sect2>
1745     <sect2 id="zend.db.adapter.other-statements">
1747         <title>Запуск других операторов БД</title>
1749         <para>
1750             Может потребоваться получить прямой доступ к
1751             объекту соединения в том виде, в котором он предоставляется
1752             расширением PHP для баз данных. Некоторые из этих расширений могут
1753             предоставлять функционал, который не поддерживается методами
1754             Zend_Db_Adapter_Abstract.
1755         </para>
1757         <para>
1758             Например, все операторы SQL, запускаемые через Zend_Db,
1759             подготавливаются перед выполнением. Однако некоторый функционал баз
1760             данных несовместим с подготовленными операторами. Операторы DDL,
1761             такие, как CREATE и ALTER, не могут подготавливаться в MySQL. Также
1762             операторы SQL не дают выигрыша от
1763             <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">кэширования запросов MySQL</ulink> в версиях MySQL до 5.1.17.
1764         </para>
1766         <para>
1767             Большинство расширений PHP для баз данных предоставляет метод для
1768             выполнения операторов SQL без их подготовки. Например, в PDO таким
1769             методом является <code>exec()</code>. Вы можете обратиться напрямую
1770             к объекту соединения в расширении PHP, используя getConnection().
1771         </para>
1773         <example id="zend.db.adapter.other-statements.example">
1774             <title>Запуск неподготовленного оператора в адаптере PDO</title>
1775             <programlisting language="php"><![CDATA[
1776 $result = $db->getConnection()->exec('DROP TABLE bugs');
1778             </programlisting>
1779         </example>
1781         <para>
1782             Так же вы можете получить доступ к другим методам или свойствам,
1783             специфическим для данного расширения. Тем не менее, следует
1784             учитывать, что, делая это, вы можете ограничить ваше приложение
1785             интерфейсом, предоставляемым расширением для определенной
1786             СУРБД.
1787         </para>
1789         <para>
1790             В будущих версиях Zend_Db будет возможность добавить точки входа
1791             методов для функционала, который является общим для поддерживаемых
1792             расширений PHP. Это не нарушит обратную совместимость.
1793         </para>
1795     </sect2>
1797     <sect2 id="zend.db.adapter.adapter-notes">
1799         <title>Примечания к отдельным адаптерам</title>
1801         <para>
1802             В данный разделе описываются различия между классами адаптеров, о
1803             которых следует знать.
1804         </para>
1806         <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
1807             <title>IBM DB2</title>
1808             <itemizedlist>
1809                 <listitem>
1810                     <para>
1811                         Для установки этого адаптера через метод factory() используйте строку 'Db2'.
1812                     </para>
1813                 </listitem>
1814                 <listitem>
1815                     <para>
1816                         Этот адаптер использует PHP-расширение ibm_db2.
1817                     </para>
1818                 </listitem>
1819                 <listitem>
1820                     <para>
1821                         IBM DB2 поддерживает как последовательности, так и
1822                         автоинкрементные ключи. Поэтому аргументы для
1823                         <code>lastInsertId()</code> являются опциональными. Если
1824                         вы не передадите аргументы, то адаптер вернет последнее
1825                         значение, сгенерированное для автоинкрементного ключа.
1826                         Если вы передадите аргументы, то адаптер вернет
1827                         последнее значение, сгенерированное последовательностью,
1828                         имя которой удовлетворяет соглашению
1829                         '<emphasis>таблица</emphasis>_<emphasis>имя</emphasis>_seq'.
1830                     </para>
1831                 </listitem>
1832             </itemizedlist>
1833         </sect3>
1835         <sect3 id="zend.db.adapter.adapter-notes.mysqli">
1836             <title>MySQLi</title>
1837             <itemizedlist>
1838                 <listitem>
1839                     <para>
1840                         Для установки этого адаптера через метод factory() используйте строку 'Mysqli'.
1841                     </para>
1842                 </listitem>
1843                 <listitem>
1844                     <para>
1845                         Этот адаптер использует PHP-расширение mysqli.
1846                     </para>
1847                 </listitem>
1848                 <listitem>
1849                     <para>
1850                         MySQL не поддерживает последовательности, поэтому
1851                         <code>lastInsertId()</code> игнорирует переданные
1852                         аргументы и всегда возвращает последнее значение,
1853                         сгенерированное для автоинкрементного ключа. Метод
1854                         <code>lastSequenceId()</code> возвращает
1855                         <constant>NULL</constant>.
1856                     </para>
1857                 </listitem>
1858             </itemizedlist>
1859         </sect3>
1861         <sect3 id="zend.db.adapter.adapter-notes.oracle">
1862             <title>Oracle</title>
1863             <itemizedlist>
1864                 <listitem>
1865                     <para>
1866                         Для установки этого адаптера через метод factory() используйте строку 'Oracle'.
1867                     </para>
1868                 </listitem>
1869                 <listitem>
1870                     <para>
1871                         Этот адаптер использует PHP-расширение oci8.
1872                     </para>
1873                 </listitem>
1874                 <listitem>
1875                     <para>
1876                         Oracle не поддерживает автоинкрементные ключи, поэтому
1877                         вы должны указывать имя последовательности для
1878                         <code>lastInsertId()</code> или
1879                         <code>lastSequenceId()</code>.
1880                     </para>
1881                 </listitem>
1882                 <listitem>
1883                     <para>
1884                         Расширение Oracle не поддерживает позиционные параметры.
1885                         Вы должны использовать именованные параметры.
1886                     </para>
1887                 </listitem>
1888                 <listitem>
1889                     <para>
1890                         На данный момент опция
1891                         <code>Zend_Db::CASE_FOLDING</code> не поддерживается
1892                         адаптером Oracle. Для того, чтобы применять эту опцию с
1893                         Oracle, вам нужно использовать адаптер PDO OCI.
1894                     </para>
1895                 </listitem>
1896             </itemizedlist>
1897         </sect3>
1899         <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
1900             <title>PDO для IBM DB2 и Informix Dynamic Server (IDS)</title>
1901             <itemizedlist>
1902                 <listitem>
1903                     <para>
1904                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Ibm'.
1905                     </para>
1906                 </listitem>
1907                 <listitem>
1908                     <para>
1909                         Этот адаптер использует PHP-расширения pdo и pdo_ibm.
1910                     </para>
1911                 </listitem>
1912                 <listitem>
1913                     <para>
1914                         Вы должны использовать расширение PDO_IBM версии не ниже
1915                         1.2.2. Если вы используете более раннюю версию этого
1916                         расширения, то должны обновить расширение PDO_IBM из
1917                         PECL.
1918                     </para>
1919                 </listitem>
1920             </itemizedlist>
1921         </sect3>
1923         <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
1924             <title>PDO Microsoft SQL Server</title>
1925             <itemizedlist>
1926                 <listitem>
1927                     <para>
1928                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Mssql'.
1929                     </para>
1930                 </listitem>
1931                 <listitem>
1932                     <para>
1933                         Этот адаптер использует PHP-расширения pdo и pdo_mssql.
1934                     </para>
1935                 </listitem>
1936                 <listitem>
1937                     <para>
1938                         Microsoft SQL Server не поддерживает последовательности,
1939                         поэтому <code>lastInsertId()</code> игнорирует
1940                         переданные аргументы и всегда возвращает последнее
1941                         значение, сгенерированное для автоинкрементного ключа.
1942                         Метод <code>lastSequenceId()</code> возвращает
1943                         <constant>NULL</constant>.
1944                     </para>
1945                 </listitem>
1946                 <listitem>
1947                     <para>
1948                         Zend_Db_Adapter_Pdo_Mssql устанавливает
1949                         <code>QUOTED_IDENTIFIER ON</code> сразу после соединения
1950                         с сервером баз данных. Это заставляет драйвер
1951                         использовать стандартные символы-ограничители
1952                         идентификаторов (<code>"</code>) вместо квадратных
1953                         скобок, которые SQL Server использует в качестве
1954                         ограничителей идентификаторов.
1955                     </para>
1956                 </listitem>
1957                 <listitem>
1958                     <para>
1959                         Вы можете указывать <code>pdoType</code> в качестве
1960                         ключа в массиве опций. Возможными значениями могут быть
1961                         "mssql" (по умолчанию),
1962                         "dblib", "freetds" или "sybase". Эта опция влияет на
1963                         префикс DSN, который используется адаптером, когда
1964                         строится строка DSN. "Freetds" и "sybase" подразумевают
1965                         префикс "sybase:", который используется для набора
1966                         библиотек <ulink url="http://www.freetds.org/">FreeTDS</ulink>. Более
1967                         подробную информацию о префиксах, используемых в этих
1968                         драйверах, читайте на
1969                         <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
1970                         http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>.
1971                     </para>
1972                 </listitem>
1973             </itemizedlist>
1974         </sect3>
1976         <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
1977             <title>PDO MySQL</title>
1978             <itemizedlist>
1979                 <listitem>
1980                     <para>
1981                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Mysql'.
1982                     </para>
1983                 </listitem>
1984                 <listitem>
1985                     <para>
1986                         Этот адаптер использует PHP-расширения pdo и pdo_mysql.
1987                     </para>
1988                 </listitem>
1989                 <listitem>
1990                     <para>
1991                         MySQL не поддерживает последовательности,
1992                         поэтому <code>lastInsertId()</code> игнорирует
1993                         переданные аргументы и всегда возвращает последнее
1994                         значение, сгенерированное для автоинкрементного ключа.
1995                         Метод <code>lastSequenceId()</code> возвращает
1996                         <constant>NULL</constant>.
1997                     </para>
1998                 </listitem>
1999             </itemizedlist>
2000         </sect3>
2002         <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
2003             <title>PDO Oracle</title>
2004             <itemizedlist>
2005                 <listitem>
2006                     <para>
2007                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Oci'.
2008                     </para>
2009                 </listitem>
2010                 <listitem>
2011                     <para>
2012                         Этот адаптер использует PHP-расширения pdo и pdo_oci.
2013                     </para>
2014                 </listitem>
2015                 <listitem>
2016                     <para>
2017                         Oracle не поддерживает автоинкрементные ключи, поэтому
2018                         вы должны указывать имя последовательности для
2019                         <code>lastInsertId()</code> или
2020                         <code>lastSequenceId()</code>.
2021                     </para>
2022                 </listitem>
2023             </itemizedlist>
2024         </sect3>
2026         <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
2027             <title>PDO PostgreSQL</title>
2028             <itemizedlist>
2029                 <listitem>
2030                     <para>
2031                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Pgsql'.
2032                     </para>
2033                 </listitem>
2034                 <listitem>
2035                     <para>
2036                         Этот адаптер использует PHP-расширения pdo и pdo_pgsql.
2037                     </para>
2038                 </listitem>
2039                 <listitem>
2040                     <para>
2041                         PostgreSQL поддерживает как последовательности, так и
2042                         автоинкрементные ключи. Поэтому аргументы для
2043                         <code>lastInsertId()</code> являются опциональными. Если
2044                         вы не передадите аргументы, то адаптер вернет последнее
2045                         значение, сгенерированное для автоинкрементного ключа.
2046                         Если вы передадите аргументы, то адаптер вернет
2047                         последнее значение, сгенерированное последовательностью,
2048                         имя которой удовлетворяет соглашению
2049                         '<emphasis>таблица</emphasis>_<emphasis>имя</emphasis>_seq'.
2050                     </para>
2051                 </listitem>
2052             </itemizedlist>
2053         </sect3>
2055         <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
2056             <title>PDO SQLite</title>
2057             <itemizedlist>
2058                 <listitem>
2059                     <para>
2060                         Для установки этого адаптера через метод factory() используйте строку 'Pdo_Sqlite'.
2061                     </para>
2062                 </listitem>
2063                 <listitem>
2064                     <para>
2065                         Этот адаптер использует PHP-расширения pdo и pdo_sqlite.
2066                     </para>
2067                 </listitem>
2068                 <listitem>
2069                     <para>
2070                         SQLite не поддерживает последовательности,
2071                         поэтому <code>lastInsertId()</code> игнорирует
2072                         переданные аргументы и всегда возвращает последнее
2073                         значение, сгенерированное для автоинкрементного ключа.
2074                         Метод <code>lastSequenceId()</code> возвращает
2075                         <constant>NULL</constant>.
2076                     </para>
2077                 </listitem>
2078                 <listitem>
2079                     <para>
2080                         Для того, чтобы соединится с базой данных SQLite2,
2081                         указывайте <code>'sqlite2'=>true</code> в массиве
2082                         параметров при создании экземпляра адаптера Pdo_Sqlite.
2083                     </para>
2084                 </listitem>
2085                 <listitem>
2086                     <para>
2087                         Для соединения с базой данных SQLite в памяти указывайте
2088                         <code>'dbname'=>':memory:'</code> в массиве параметров
2089                         при создании экземпляра адаптера Pdo_Sqlite.
2090                     </para>
2091                 </listitem>
2092                 <listitem>
2093                     <para>
2094                         Старые версии драйвера SQLite для PHP могут не
2095                         поддерживать команды PRAGMA, необходимые для обеспечения
2096                         использования коротких имен столбцов в результатах. Если
2097                         имеются проблемы с тем, что результаты возвращаются с
2098                         ключами в виде "tablename.columnname", когда производится запрос с объединением таблиц, то следует обновить PHP до текущей версии.
2099                     </para>
2100                 </listitem>
2101             </itemizedlist>
2102         </sect3>
2104         <sect3 id="zend.db.adapter.adapter-notes.firebird">
2105             <title>Firebird/Interbase</title>
2106             <itemizedlist>
2107                 <listitem>
2108                     <para>
2109                         Этот адаптер использует PHP-расширение php_interbase.
2110                     </para>
2111                 </listitem>
2112                 <listitem>
2113                     <para>
2114                         Firebird/interbase  не поддерживает автоинкрементные
2115                         ключи, поэтому вы должны указывать имя
2116                         последовательности для
2117                         <code>lastInsertId()</code> или
2118                         <code>lastSequenceId()</code>.
2119                     </para>
2120                 </listitem>
2121                 <listitem>
2122                     <para>
2123                         На данный момент опция
2124                         <code>Zend_Db::CASE_FOLDING</code> не поддерживается
2125                         адаптером Firebird/interbase. Не заключенные в кавычки
2126                         идентификаторы автоматически возвращаются в верхнем
2127                         регистре..
2128                     </para>
2129                 </listitem>
2130             </itemizedlist>
2131         </sect3>
2133     </sect2>
2135 </sect1>
2136 <!--
2137 vim:se ts=4 sw=4 et: