[ZF-10089] Zend_Log
[zend.git] / documentation / manual / es / module_specs / Zend_Db_Adapter.xml
blobc41a9e487230d2d29569ab1e145593bba530e47f
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 20115 -->
3     <!-- Reviewed: no -->
4 <sect1 id="zend.db.adapter">
6     <title>Zend_Db_Adapter</title>
8     <para>
9         <classname>Zend_Db</classname> y sus clases relacionadas proporcionan
10         una interfaz simple de base de datos <acronym>SQL</acronym> para Zend
11         Framework. El <classname>Zend_Db_Adapter</classname> es la clase base
12         que se utiliza para conectar su aplicación <acronym>PHP</acronym> A una
13         base de datos ( <acronym>RDBMS</acronym> ). Existen diferentes clases
14         Adapters(Adaptador) para cada tipo de base de datos (
15             <acronym>RDBMS</acronym> ). </para>
17     <para> Las clases Adapters de <classname>Zend_Db</classname> crean un puente
18         entre las extensiones de base de datos de <acronym>PHP</acronym> hacia
19         una interfaz común, para ayudarle a escribir aplicaciones
20             <acronym>PHP</acronym> una sola vez y poder desplegar múltiples
21         tipos de base de datos ( <acronym>RDBMS</acronym> ) con muy poco
22         esfuerzo. </para>
24     <para> La Interfaz de la clase adaptador (adapter) es similar a la intefaz
25         de la extensión <ulink url="http://www.php.net/pdo">PHP Data
26             Objects</ulink> . <classname>Zend_Db</classname> proporciona clases
27         Adaptadoras para los drivers <acronym>PDO</acronym> de los siguientes
28         tipos de <acronym>RDBMS</acronym> : </para>
30     <itemizedlist>
31         <listitem>
32             <para> IBM DB2 e Informix Dynamic Server (IDS), usando la extensión
33                     <acronym>PHP</acronym>
34                 <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
35             </para>
36         </listitem>
37         <listitem>
38             <para> MySQL, usando la extensión <acronym>PHP</acronym>
39                 <ulink url="http://www.php.net/pdo-mysql"> pdo_mysql </ulink>
40             </para>
41         </listitem>
42         <listitem>
43             <para> Microsoft SQL Server, usando la extensión
44                     <acronym>PHP</acronym>
45                 <ulink url="http://www.php.net/pdo-mssql"> pdo_mssql </ulink>
46             </para>
47         </listitem>
48         <listitem>
49             <para> Oracle, usando la extensión <acronym>PHP</acronym>
50                 <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
51             </para>
52         </listitem>
53         <listitem>
54             <para> PostgreSQL, usando la extensión <acronym>PHP</acronym>
55                 <ulink url="http://www.php.net/pdo-pgsql"> pdo_pgsql </ulink>
56             </para>
57         </listitem>
58         <listitem>
59             <para> SQLite, usando la extensión <acronym>PHP</acronym>
60                 <ulink url="http://www.php.net/pdo-sqlite"> pdo_sqlite </ulink>
61             </para>
62         </listitem>
64     </itemizedlist>
66     <para> Ademas, <classname>Zend_Db</classname> proporciona clases Adaptadoras
67         que utilizan las extensiones de base de datos de <acronym>PHP</acronym>
68         de los siguientes tipos: </para>
70     <itemizedlist>
71         <listitem>
72             <para> MySQL, usando la extensión <acronym>PHP</acronym>
73                 <ulink url="http://www.php.net/mysqli">mysqli</ulink>
74             </para>
75         </listitem>
76         <listitem>
77             <para> Oracle, usando la extensión <acronym>PHP</acronym>
78                 <ulink url="http://www.php.net/oci8">oci8</ulink>
79             </para>
80         </listitem>
81         <listitem>
82             <para> IBM DB2, usando la extensión <acronym>PHP</acronym>
83                 <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
84             </para>
85         </listitem>
86         <listitem>
87             <para> Firebird/Interbase, usando la extensión
88                     <acronym>PHP</acronym>
89                 <ulink url="http://www.php.net/ibase"> php_interbase </ulink>
90             </para>
91         </listitem>
92     </itemizedlist>
94     <note>
95         <para> Cada Zend_Db_Adaptador utiliza una extensión
96                 <acronym>PHP</acronym> . Se debe de tener habilitada la
97             respectiva extensión en su entorno <acronym>PHP</acronym> para
98             utilizar un <classname>Zend_Db_Adapter</classname> . Por ejemplo, si
99             se utiliza una clase <classname>Zend_Db_Adapter</classname> basada
100             en <acronym>PDO</acronym> , tiene que habilitar tanto la extensión
101                 <acronym>PDO</acronym> como el driver <acronym>PDO</acronym> del
102             tipo de base de datos que se utiliza. </para>
103     </note>
105     <sect2 id="zend.db.adapter.connecting">
107         <title> Conexión a una Base de Datos utilizando un Adaptador </title>
109         <para> Esta sección describe cómo crear una instancia de un Adaptador de
110             base de datos. Esto corresponde a establecer una conexión a un
111             servidor de Base de Datos ( <acronym>RDBMS</acronym> ) desde su
112             aplicación <acronym>PHP</acronym> . </para>
114         <sect3 id="zend.db.adapter.connecting.constructor">
116             <title>Usando un Constructor de Zend_Db Adapter</title>
118             <para> Se puede crear una instancia de un Adaptador utilizando su
119                 constructor. Un constructor de adaptador toma un argumento, que
120                 es un conjunto de parámetros utilizados para declarar la
121                 conexión. </para>
123             <example id="zend.db.adapter.connecting.constructor.example">
124                 <title>Usando el Constructor de un Adaptador</title>
125                 <programlisting language="php"><![CDATA[
126 $db = new Zend_Db_Adapter_Pdo_Mysql(array(
127     'host'     => '127.0.0.1',
128     'username' => 'webuser',
129     'password' => 'xxxxxxxx',
130     'dbname'   => 'test'
132 ]]></programlisting>
133             </example>
135         </sect3>
137         <sect3 id="zend.db.adapter.connecting.factory">
139             <title>Usando el Zend_Db Factory</title>
141             <para> Como alternativa a la utilización directa del constructor de
142                 un adaptador, se puede crear una instancia del adaptador que use
143                 el método estático <methodname>Zend_Db::factory()</methodname> .
144                 Este método carga dinámicamente el archivo de clase Adaptador
145                 bajo demanda, usando <link linkend="zend.loader.load.class">
146                     Zend_Loader::loadClass() </link> . </para>
148             <para> El primer argumento es una cadena que nombra al nombre base
149                 de la clase Adaptador. Por ejemplo, la cadena '
150                     <classname>Pdo_Mysql</classname> ' corresponde a la clase
151                     <classname>Zend_Db_Adapter_Pdo_Mysql</classname> . El
152                 segundo argumento es el mismo array de parámetros que hubiera
153                 enviado al constructor del adaptador. </para>
155             <example id="zend.db.adapter.connecting.factory.example">
156                 <title>Usando el Adaptador del método factory</title>
157                 <programlisting language="php"><![CDATA[
158 // No necesitamos la siguiente declaración, porque
159 // el archivo Zend_Db_Adapter_Pdo_Mysql será cargado para nosotros por el método
160 // factory de Zend_Db.
162 // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
164 // carga automaticamente la clase Zend_Db_Adapter_Pdo_Mysql
165 // y crea una instancia de la misma
166 $db = Zend_Db::factory('Pdo_Mysql', array(
167     'host'     => '127.0.0.1',
168     'username' => 'webuser',
169     'password' => 'xxxxxxxx',
170     'dbname'   => 'test'
172 ]]></programlisting>
173             </example>
175             <para> Si crea su propia clase que extiende a
176                     <classname>Zend_Db_Adapter_Abstract</classname> , pero no
177                 nombra su clase con el prefijo de paquete "
178                     <classname>Zend_Db_Adapter</classname> ", se puede utilizar
179                 el método <methodname>factory()</methodname> para cargar su
180                 adaptador si se especifica la parte principal de la clase del
181                 adaptador con la clave "adapterNamespace" en el conjunto de
182                 parámetros </para>
184             <example id="zend.db.adapter.connecting.factory.example2">
185                 <title> Usando el método factory para una clase Adaptador
186                     personalizada </title>
187                 <programlisting language="php"><![CDATA[
188 // No tenemos que cargar el archivo de clase Adaptador
189 // porque será cargado para nosotros por el método factory de Zend_Db.
191 // Automáticamente carga la clase MyProject_Db_Adapter_Pdo_Mysql
192 // y crea una instancia de ella.
194 $db = Zend_Db::factory('Pdo_Mysql', array(
195     'host'             => '127.0.0.1',
196     'username'         => 'webuser',
197     'password'         => 'xxxxxxxx',
198     'dbname'           => 'test',
199     'adapterNamespace' => 'MyProject_Db_Adapter'
201 ]]></programlisting>
202             </example>
204         </sect3>
206         <sect3 id="zend.db.adapter.connecting.factory-config">
208             <title>Uso de Zend_Config con Zend_Db Factory</title>
210             <para> Opcionalmente, se puede especificar cualquier argumento del
211                 método <methodname>factory()</methodname> como un objeto de tipo
212                     <link linkend="zend.config">Zend_Config</link> . </para>
214             <para> Si el primer argumento es un objeto de configuración, se
215                 espera que contenga una propiedad llamada
216                     <property>adapter</property> , conteniendo la cadena que da
217                 nombre al nombre base de la clase de adaptador. Opcionalmente,
218                 el objeto puede contener una propiedad llamada
219                     <property>params</property> , con subpropiedades
220                 correspondientes a nombres de parámetros del adaptador. Esto es
221                 usado sólo si el segundo argumento del método
222                     <methodname>factory()</methodname> se ha omitido. </para>
224             <example id="zend.db.adapter.connecting.factory.example1">
225                 <title> Uso del método factory del Adaptador con un objeto
226                     Zend_Config </title>
227                 <para> En el siguiente ejemplo, un objeto
228                         <classname>Zend_Config</classname> es creado usando un
229                     array. También puedes cargar los datos de un archivo
230                     externo, por ejemplo con <link
231                         linkend="zend.config.adapters.ini"> Zend_Config_Ini
232                     </link> o <link linkend="zend.config.adapters.xml">
233                         Zend_Config_Xml </link> . </para>
234                 <programlisting language="php"><![CDATA[
235 $config = new Zend_Config(
236     array(
237         'database' => array(
238             'adapter' => 'Mysqli',
239             'params' => array(
240                 'dbname' => 'test',
241                 'username' => 'webuser',
242                 'password' => 'secret',
243             )
244         )
245     )
248 $db = Zend_Db::factory($config->database);
249 ]]></programlisting>
250             </example>
252             <para> El segundo argumento del método
253                     <methodname>factory()</methodname> puede ser un array
254                 asociativo con entradas correspondientes a los parámetros del
255                 adaptador. Este argumento es opcional. Si el primer argumento es
256                 de tipo <classname>Zend_Config</classname> , se asume que tiene
257                 todos los parametros, y el segundo argumento es ignorado. </para>
259         </sect3>
261         <sect3 id="zend.db.adapter.connecting.parameters">
263             <title>Parámetros del Adaptador</title>
265             <para> El siguiente listado explica parámetros comunes reconocidos
266                 por Adaptador de clases <classname>Zend_Db</classname> . </para>
268             <itemizedlist>
269                 <listitem>
270                     <para>
271                         <emphasis>host</emphasis> : una string conteniendo un
272                         nombre de host o dirección IP del servidor de base de
273                         datos. Si la base de datos está corriendo sobre el mismo
274                         host que la aplicación <acronym>PHP</acronym> , usted
275                         puede utilizar 'localhost' o '127.0.0.1'. </para>
276                 </listitem>
277                 <listitem>
278                     <para>
279                         <emphasis>username</emphasis> : identificador de cuenta
280                         para autenticar una conexión al servidor
281                             <acronym>RDBMS</acronym> . </para>
282                 </listitem>
283                 <listitem>
284                     <para>
285                         <emphasis>password</emphasis> : la contraseña de la
286                         cuenta para la autenticación de credenciales de conexión
287                         con el servidor <acronym>RDBMS</acronym>
288                     </para>
289                 </listitem>
290                 <listitem>
291                     <para>
292                         <emphasis>dbname</emphasis> : nombre de la base de datos
293                         en el servidor <acronym>RDBMS</acronym> . </para>
294                 </listitem>
295                 <listitem>
296                     <para>
297                         <emphasis>port</emphasis> : algunos servidores
298                             <acronym>RDBMS</acronym> pueden aceptar conexiones
299                         de red sobre un número de puerto específico. El
300                         parámetro del puerto le permite especificar el puerto al
301                         que su aplicación <acronym>PHP</acronym> se conecta,
302                         para que concuerde el puerto configurado en el servidor
303                             <acronym>RDBMS</acronym> . </para>
304                 </listitem>
305                 <listitem>
306                     <para>
307                         <emphasis>charset</emphasis> : specify the charset used
308                         for the connection. </para>
309                 </listitem>
311                 <listitem>
312                     <para>
313                         <emphasis>options</emphasis> : : este parámetro es un
314                         array asociativo de opciones que son genéricas a todas
315                         las clases <classname>Zend_Db_Adapter</classname> .
316                     </para>
317                 </listitem>
318                 <listitem>
319                     <para>
320                         <emphasis> driver_options </emphasis> : este parámetro
321                         es un array asociativo de opciones adicionales para una
322                         extensión de base de datos dada. un uso típico de este
323                         parámetro es establecer atributos de un driver
324                             <acronym>PDO</acronym> . </para>
325                 </listitem>
326                 <listitem>
327                     <para>
328                         <emphasis> adapterNamespace </emphasis> : nombre de la
329                         parte inicial del nombre de las clase para el adaptador,
330                         en lugar de ' <classname>Zend_Db_Adapter</classname> '.
331                         Utilice esto si usted necesita usar el método
332                             <methodname>factory()</methodname> para cargar un
333                         adaptador de clase de base de datos que no sea de Zend.
334                     </para>
335                 </listitem>
336             </itemizedlist>
338             <example id="zend.db.adapter.connecting.parameters.example1">
339                 <title> Passing the case-folding option to the factory </title>
340                 <para> Usted puede pasar esta opción específica por la constante
341                         <constant>Zend_Db::CASE_FOLDING</constant> . Este
342                     corresponde al atributo <constant>ATTR_CASE</constant> en
343                     los drivers de base de datos <acronym>PDO</acronym> e IBM
344                     DB2, ajustando la sensibilidad de las claves tipo cadena en
345                     los resultados de consultas. La opción toma los valores
346                         <constant>Zend_Db::CASE_NATURAL</constant> (el
347                     predeterminado), <constant>Zend_Db::CASE_UPPER</constant> ,
348                     y <constant>Zend_Db::CASE_LOWER</constant> . </para>
349                 <programlisting language="php"><![CDATA[
350 $options = array(
351     Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
354 $params = array(
355     'host'           => '127.0.0.1',
356     'username'       => 'webuser',
357     'password'       => 'xxxxxxxx',
358     'dbname'         => 'test',
359     'options'        => $options
362 $db = Zend_Db::factory('Db2', $params);
363 ]]></programlisting>
364             </example>
366             <example id="zend.db.adapter.connecting.parameters.example2">
367                 <title> Passing the auto-quoting option to the factory </title>
368                 <para> Usted puede especificar esta opción por la constante
369                         <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> .
370                     Si el valor es <constant>TRUE</constant> (el
371                     predeterminado), los identificadores como nombres de tabla,
372                     nombres de columna, e incluso los alias son delimitados en
373                     la sintaxis <acronym>SQL</acronym> generada por el Adatador
374                     del objeto. Esto hace que sea sencillo utilizar
375                     identificadores que contengan palabras reservadas de
376                         <acronym>SQL</acronym> , o caracteres especiales. Si el
377                     valor es <constant>FALSE</constant> , los identificadores no
378                     son delimitados automáticamente. Si usted necesita delimitar
379                     identificadores, debe hacer usted mismo utilizando el método
380                         <methodname>quoteIdentifier()</methodname> . </para>
381                 <programlisting language="php"><![CDATA[
382 $options = array(
383     Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
386 $params = array(
387     'host'           => '127.0.0.1',
388     'username'       => 'webuser',
389     'password'       => 'xxxxxxxx',
390     'dbname'         => 'test',
391     'options'        => $options
394 $db = Zend_Db::factory('Pdo_Mysql', $params);
395 ]]></programlisting>
396             </example>
398             <example id="zend.db.adapter.connecting.parameters.example3">
399                 <title>Passing PDO driver options to the factory</title>
400                 <programlisting language="php"><![CDATA[
401 $pdoParams = array(
402     PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
405 $params = array(
406     'host'           => '127.0.0.1',
407     'username'       => 'webuser',
408     'password'       => 'xxxxxxxx',
409     'dbname'         => 'test',
410     'driver_options' => $pdoParams
413 $db = Zend_Db::factory('Pdo_Mysql', $params);
415 echo $db->getConnection()
416         ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
417 ]]></programlisting>
418             </example>
420             <example id="zend.db.adapter.connecting.parameters.example4">
421                 <title>Passing Serialization Options to the Factory</title>
422                 <programlisting language="php"><![CDATA[
423 $options = array(
424     Zend_Db::ALLOW_SERIALIZATION => false
427 $params = array(
428     'host'           => '127.0.0.1',
429     'username'       => 'webuser',
430     'password'       => 'xxxxxxxx',
431     'dbname'         => 'test',
432     'options'        => $options
435 $db = Zend_Db::factory('Pdo_Mysql', $params);
436 ]]></programlisting>
437             </example>
439         </sect3>
441         <sect3 id="zend.db.adapter.connecting.getconnection">
442             <title>Managing Lazy Connections</title>
444             <para> Creating an instance of an Adapter class does not immediately
445                 connect to the <acronym>RDBMS</acronym> server. The Adapter
446                 saves the connection parameters, and makes the actual connection
447                 on demand, the first time you need to execute a query. This
448                 ensures that creating an Adapter object is quick and
449                 inexpensive. You can create an instance of an Adapter even if
450                 you are not certain that you need to run any database queries
451                 during the current request your application is serving. </para>
453             <para> If you need to force the Adapter to connect to the
454                     <acronym>RDBMS</acronym> , use the
455                     <methodname>getConnection()</methodname> method. This method
456                 returns an object for the connection as represented by the
457                 respective <acronym>PHP</acronym> database extension. For
458                 example, if you use any of the Adapter classes for
459                     <acronym>PDO</acronym> drivers, then
460                     <methodname>getConnection()</methodname> returns the
461                     <acronym>PDO</acronym> object, after initiating it as a live
462                 connection to the specific database. </para>
464             <para> It can be useful to force the connection if you want to catch
465                 any exceptions it throws as a result of invalid account
466                 credentials, or other failure to connect to the
467                     <acronym>RDBMS</acronym> server. These exceptions are not
468                 thrown until the connection is made, so it can help simplify
469                 your application code if you handle the exceptions in one place,
470                 instead of at the time of the first query against the database. </para>
472             <para> Additionally, an adapter can get serialized to store it, for
473                 example, in a session variable. This can be very useful not only
474                 for the adapter itself, but for other objects that aggregate it,
475                 like a <classname>Zend_Db_Select</classname> object. By default,
476                 adapters are allowed to be serialized, if you don't want it, you
477                 should consider passing the
478                     <constant>Zend_Db::ALLOW_SERIALIZATION</constant> option
479                 with <constant>FALSE</constant> , see the example above. To
480                 respect lazy connections principle, the adapter won't reconnect
481                 itself after being unserialized. You must then call
482                     <methodname>getConnection()</methodname> yourself. You can
483                 make the adapter auto-reconnect by passing the
484                     <constant>Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE</constant>
485                 with <constant>TRUE</constant> as an adapter option. </para>
487             <example id="zend.db.adapter.connecting.getconnection.example">
488                 <title>Handling connection exceptions</title>
489                 <programlisting language="php"><![CDATA[
490 try {
491     $db = Zend_Db::factory('Pdo_Mysql', $parameters);
492     $db->getConnection();
493 } catch (Zend_Db_Adapter_Exception $e) {
494     // perhaps a failed login credential, or perhaps the RDBMS is not running
495 } catch (Zend_Exception $e) {
496     // perhaps factory() failed to load the specified Adapter class
498 ]]></programlisting>
499             </example>
501         </sect3>
503     </sect2>
505     <sect2 id="zend.db.adapter.example-database">
507         <title>La base de datos de ejemplo</title>
509         <para> En la documentación de las clases <classname>Zend_Db</classname>
510             , usamos un conjunto sencillo de tablas para ilustrar el uso de las
511             clases y métodos. Estas tablas de ejemplo permiten almacenar
512             información para localizar bugs en un proyecto de desarrollo de
513             software. La base de datos contiene cuatro tablas: </para>
515         <itemizedlist>
516             <listitem>
517                 <para>
518                     <emphasis>accounts</emphasis> almacena información sobre
519                     cada usuario que hace el seguimiento de bugs. </para>
520             </listitem>
521             <listitem>
522                 <para>
523                     <emphasis>products</emphasis> almacena información sobre
524                     cada producto para el que pueden registrarse bugs. </para>
525             </listitem>
526             <listitem>
527                 <para>
528                     <emphasis>bugs</emphasis> almacena información sobre bugs,
529                     incluyendo el estado actual del bug, la persona que informó
530                     sobre el bug, la persona que está asignada para corregir el
531                     bug, y la persona que está asignada para verificar la
532                     corrección. </para>
533             </listitem>
534             <listitem>
535                 <para>
536                     <emphasis>bugs_products</emphasis> stores a relationship
537                     between bugs and products. This implements a many-to-many
538                     relationship, because a given bug may be relevant to
539                     multiple products, and of course a given product can have
540                     multiple bugs. </para>
541             </listitem>
542         </itemizedlist>
544         <para> La siguiente definición de datos <acronym>SQL</acronym> en
545             lenguaje pseudocódigo describe las tablas de esta base de datos de
546             ejemplo. Estas tablas de ejemplo son usadas ampliamente por los
547             tests unitarios automatizados de <classname>Zend_Db</classname> . </para>
549         <programlisting language="sql"><![CDATA[
550 CREATE TABLE accounts (
551   account_name      VARCHAR(100) NOT NULL PRIMARY KEY
554 CREATE TABLE products (
555   product_id        INTEGER NOT NULL PRIMARY KEY,
556   product_name      VARCHAR(100)
559 CREATE TABLE bugs (
560   bug_id            INTEGER NOT NULL PRIMARY KEY,
561   bug_description   VARCHAR(100),
562   bug_status        VARCHAR(20),
563   reported_by       VARCHAR(100) REFERENCES accounts(account_name),
564   assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
565   verified_by       VARCHAR(100) REFERENCES accounts(account_name)
568 CREATE TABLE bugs_products (
569   bug_id            INTEGER NOT NULL REFERENCES bugs,
570   product_id        INTEGER NOT NULL REFERENCES products,
571   PRIMARY KEY       (bug_id, product_id)
573 ]]></programlisting>
575         <para> Also notice that the <code>bugs</code> table contains multiple
576             foreign key references to the <code>accounts</code> table. Each of
577             these foreign keys may reference a different row in the
578                 <code>accounts</code> table for a given bug. </para>
580         <para> The diagram below illustrates the physical data model of the
581             example database. </para>
583         <para>
584             <inlinegraphic width="387" scale="100" align="center"
585                 valign="middle"
586                 fileref="figures/zend.db.adapter.example-database.png"
587                 format="PNG"/>
588         </para>
590     </sect2>
592     <sect2 id="zend.db.adapter.select">
594         <title>Reading Query Results</title>
596         <para> This section describes methods of the Adapter class with which
597             you can run SELECT queries and retrieve the query results. </para>
599         <sect3 id="zend.db.adapter.select.fetchall">
601             <title>Fetching a Complete Result Set</title>
603             <para> You can run a <acronym>SQL</acronym> SELECT query and
604                 retrieve its results in one step using the
605                     <methodname>fetchAll()</methodname> method. </para>
607             <para> The first argument to this method is a string containing a
608                 SELECT statement. Alternatively, the first argument can be an
609                 object of class <link linkend="zend.db.select"
610                     >Zend_Db_Select</link> . The Adapter automatically converts
611                 this object to a string representation of the SELECT statement. </para>
613             <para> The second argument to <methodname>fetchAll()</methodname> is
614                 an array of values to substitute for parameter placeholders in
615                 the <acronym>SQL</acronym> statement. </para>
617             <example id="zend.db.adapter.select.fetchall.example">
618                 <title>Using fetchAll()</title>
619                 <programlisting language="php"><![CDATA[
620 $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
622 $result = $db->fetchAll($sql, 2);
623 ]]></programlisting>
624             </example>
626         </sect3>
628         <sect3 id="zend.db.adapter.select.fetch-mode">
630             <title>Changing the Fetch Mode</title>
632             <para> By default, <methodname>fetchAll()</methodname> returns an
633                 array of rows, each of which is an associative array. The keys
634                 of the associative array are the columns or column aliases named
635                 in the select query. </para>
637             <para> You can specify a different style of fetching results using
638                 the <methodname>setFetchMode()</methodname> method. The modes
639                 supported are identified by constants: </para>
641             <itemizedlist>
642                 <listitem>
643                     <para>
644                         <constant>Zend_Db::FETCH_ASSOC</constant> : return data
645                         in an array of associative arrays. The array keys are
646                         column names, as strings. This is the default fetch mode
647                         for <classname>Zend_Db_Adapter</classname> classes. </para>
648                     <para> Note that if your select-list contains more than one
649                         column with the same name, for example if they are from
650                         two different tables in a JOIN, there can be only one
651                         entry in the associative array for a given name. If you
652                         use the FETCH_ASSOC mode, you should specify column
653                         aliases in your SELECT query to ensure that the names
654                         result in unique array keys. </para>
655                     <para> By default, these strings are returned as they are
656                         returned by the database driver. This is typically the
657                         spelling of the column in the <acronym>RDBMS</acronym>
658                         server. You can specify the case for these strings,
659                         using the <constant>Zend_Db::CASE_FOLDING</constant>
660                         option. Specify this when instantiating the Adapter. See
661                             <xref
662                             linkend="zend.db.adapter.connecting.parameters.example1"
663                         /> . </para>
664                 </listitem>
665                 <listitem>
666                     <para>
667                         <constant>Zend_Db::FETCH_NUM</constant> : return data in
668                         an array of arrays. The arrays are indexed by integers,
669                         corresponding to the position of the respective field in
670                         the select-list of the query. </para>
671                 </listitem>
672                 <listitem>
673                     <para>
674                         <constant>Zend_Db::FETCH_BOTH</constant> : return data
675                         in an array of arrays. The array keys are both strings
676                         as used in the FETCH_ASSOC mode, and integers as used in
677                         the FETCH_NUM mode. Note that the number of elements in
678                         the array is double that which would be in the array if
679                         you used either FETCH_ASSOC or FETCH_NUM. </para>
680                 </listitem>
681                 <listitem>
682                     <para>
683                         <constant>Zend_Db::FETCH_COLUMN</constant> : return data
684                         in an array of values. The value in each array is the
685                         value returned by one column of the result set. By
686                         default, this is the first column, indexed by 0. </para>
687                 </listitem>
688                 <listitem>
689                     <para>
690                         <constant>Zend_Db::FETCH_OBJ</constant> : return data in
691                         an array of objects. The default class is the
692                             <acronym>PHP</acronym> built-in class stdClass.
693                         Columns of the result set are available as public
694                         properties of the object. </para>
695                 </listitem>
696             </itemizedlist>
698             <example id="zend.db.adapter.select.fetch-mode.example">
699                 <title>Using setFetchMode()</title>
700                 <programlisting language="php"><![CDATA[
701 $db->setFetchMode(Zend_Db::FETCH_OBJ);
703 $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
705 // $result is an array of objects
706 echo $result[0]->bug_description;
707 ]]></programlisting>
708             </example>
710         </sect3>
712         <sect3 id="zend.db.adapter.select.fetchassoc">
714             <title>Fetching a Result Set as an Associative Array</title>
716             <para> The <methodname>fetchAssoc()</methodname> method returns data
717                 in an array of associative arrays, regardless of what value you
718                 have set for the fetch mode. </para>
720             <example id="zend.db.adapter.select.fetchassoc.example">
721                 <title>Using fetchAssoc()</title>
722                 <programlisting language="php"><![CDATA[
723 $db->setFetchMode(Zend_Db::FETCH_OBJ);
725 $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
727 // $result is an array of associative arrays, in spite of the fetch mode
728 echo $result[0]['bug_description'];
729 ]]></programlisting>
730             </example>
732         </sect3>
734         <sect3 id="zend.db.adapter.select.fetchcol">
736             <title>Fetching a Single Column from a Result Set</title>
738             <para> The <methodname>fetchCol()</methodname> method returns data
739                 in an array of values, regardless of the value you have set for
740                 the fetch mode. This only returns the first column returned by
741                 the query. Any other columns returned by the query are
742                 discarded. If you need to return a column other than the first,
743                 see <xref linkend="zend.db.statement.fetching.fetchcolumn"/> . </para>
745             <example id="zend.db.adapter.select.fetchcol.example">
746                 <title>Using fetchCol()</title>
747                 <programlisting language="php"><![CDATA[
748 $db->setFetchMode(Zend_Db::FETCH_OBJ);
750 $result = $db->fetchCol(
751     'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
753 // contains bug_description; bug_id is not returned
754 echo $result[0];
755 ]]></programlisting>
756             </example>
758         </sect3>
760         <sect3 id="zend.db.adapter.select.fetchpairs">
762             <title>Fetching Key-Value Pairs from a Result Set</title>
764             <para> The <methodname>fetchPairs()</methodname> method returns data
765                 in an array of key-value pairs, as an associative array with a
766                 single entry per row. The key of this associative array is taken
767                 from the first column returned by the SELECT query. The value is
768                 taken from the second column returned by the SELECT query. Any
769                 other columns returned by the query are discarded. </para>
771             <para> You should design the SELECT query so that the first column
772                 returned has unique values. If there are duplicates values in
773                 the first column, entries in the associative array will be
774                 overwritten. </para>
776             <example id="zend.db.adapter.select.fetchpairs.example">
777                 <title>Using fetchPairs()</title>
778                 <programlisting language="php"><![CDATA[
779 $db->setFetchMode(Zend_Db::FETCH_OBJ);
781 $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
783 echo $result[2];
784 ]]></programlisting>
785             </example>
786         </sect3>
788         <sect3 id="zend.db.adapter.select.fetchrow">
790             <title>Fetching a Single Row from a Result Set</title>
792             <para> The <methodname>fetchRow()</methodname> method returns data
793                 using the current fetch mode, but it returns only the first row
794                 fetched from the result set. </para>
796             <example id="zend.db.adapter.select.fetchrow.example">
797                 <title>Using fetchRow()</title>
798                 <programlisting language="php"><![CDATA[
799 $db->setFetchMode(Zend_Db::FETCH_OBJ);
801 $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
803 // note that $result is a single object, not an array of objects
804 echo $result->bug_description;
805 ]]></programlisting>
806             </example>
807         </sect3>
809         <sect3 id="zend.db.adapter.select.fetchone">
811             <title>Fetching a Single Scalar from a Result Set</title>
813             <para> The <methodname>fetchOne()</methodname> method is like a
814                 combination of <methodname>fetchRow()</methodname> with
815                     <methodname>fetchCol()</methodname> , in that it returns
816                 data only for the first row fetched from the result set, and it
817                 returns only the value of the first column in that row.
818                 Therefore it returns only a single scalar value, not an array or
819                 an object. </para>
821             <example id="zend.db.adapter.select.fetchone.example">
822                 <title>Using fetchOne()</title>
823                 <programlisting language="php"><![CDATA[
824 $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
826 // this is a single string value
827 echo $result;
828 ]]></programlisting>
829             </example>
830         </sect3>
832     </sect2>
834     <sect2 id="zend.db.adapter.write">
836         <title>Writing Changes to the Database</title>
838         <para> You can use the Adapter class to write new data or change
839             existing data in your database. This section describes methods to do
840             these operations. </para>
842         <sect3 id="zend.db.adapter.write.insert">
844             <title>Inserting Data</title>
846             <para> You can add new rows to a table in your database using the
847                     <methodname>insert()</methodname> method. The first argument
848                 is a string that names the table, and the second argument is an
849                 associative array, mapping column names to data values. </para>
851             <example id="zend.db.adapter.write.insert.example">
852                 <title>Inserting in a Table</title>
853                 <programlisting language="php"><![CDATA[
854 $data = array(
855     'created_on'      => '2007-03-22',
856     'bug_description' => 'Something wrong',
857     'bug_status'      => 'NEW'
860 $db->insert('bugs', $data);
861 ]]></programlisting>
862             </example>
864             <para> Columns you exclude from the array of data are not specified
865                 to the database. Therefore, they follow the same rules that an
866                     <acronym>SQL</acronym> INSERT statement follows: if the
867                 column has a DEFAULT clause, the column takes that value in the
868                 row created, otherwise the column is left in a  <acronym>NULL</acronym> state. </para>
870             <para> By default, the values in your data array are inserted using
871                 parameters. This reduces risk of some types of security issues.
872                 You don't need to apply escaping or quoting to values in the
873                 data array. </para>
875             <para> You might need values in the data array to be treated as
876                     <acronym>SQL</acronym> expressions, in which case they
877                 should not be quoted. By default, all data values passed as
878                 strings are treated as string literals. To specify that the
879                 value is an <acronym>SQL</acronym> expression and therefore
880                 should not be quoted, pass the value in the data array as an
881                 object of type <classname>Zend_Db_Expr</classname> instead of a
882                 plain string. </para>
884             <example id="zend.db.adapter.write.insert.example2">
885                 <title>Inserting Expressions in a Table</title>
886                 <programlisting language="php"><![CDATA[
887 $data = array(
888     'created_on'      => new Zend_Db_Expr('CURDATE()'),
889     'bug_description' => 'Something wrong',
890     'bug_status'      => 'NEW'
893 $db->insert('bugs', $data);
894 ]]></programlisting>
895             </example>
897         </sect3>
899         <sect3 id="zend.db.adapter.write.lastinsertid">
901             <title>Retrieving a Generated Value</title>
903             <para> Some <acronym>RDBMS</acronym> brands support
904                 auto-incrementing primary keys. A table defined this way
905                 generates a primary key value automatically during an INSERT of
906                 a new row. The return value of the
907                     <methodname>insert()</methodname> method is
908                     <emphasis>not</emphasis> the last inserted ID, because the
909                 table might not have an auto-incremented column. Instead, the
910                 return value is the number of rows affected (usually 1). </para>
912             <para> If your table is defined with an auto-incrementing primary
913                 key, you can call the <methodname>lastInsertId()</methodname>
914                 method after the insert. This method returns the last value
915                 generated in the scope of the current database connection. </para>
917             <example id="zend.db.adapter.write.lastinsertid.example-1">
918                 <title>Using lastInsertId() for an Auto-Increment Key</title>
919                 <programlisting language="php"><![CDATA[
920 $db->insert('bugs', $data);
922 // return the last value generated by an auto-increment column
923 $id = $db->lastInsertId();
924 ]]></programlisting>
925             </example>
927             <para> Some <acronym>RDBMS</acronym> brands support a sequence
928                 object, which generates unique values to serve as primary key
929                 values. To support sequences, the
930                     <methodname>lastInsertId()</methodname> method accepts two
931                 optional string arguments. These arguments name the table and
932                 the column, assuming you have followed the convention that a
933                 sequence is named using the table and column names for which the
934                 sequence generates values, and a suffix "_seq". This is based on
935                 the convention used by PostgreSQL when naming sequences for
936                 SERIAL columns. For example, a table "bugs" with primary key
937                 column "bug_id" would use a sequence named "bugs_bug_id_seq". </para>
939             <example id="zend.db.adapter.write.lastinsertid.example-2">
940                 <title>Using lastInsertId() for a Sequence</title>
941                 <programlisting language="php"><![CDATA[
942 $db->insert('bugs', $data);
944 // return the last value generated by sequence 'bugs_bug_id_seq'.
945 $id = $db->lastInsertId('bugs', 'bug_id');
947 // alternatively, return the last value generated by sequence 'bugs_seq'.
948 $id = $db->lastInsertId('bugs');
949 ]]></programlisting>
950             </example>
952             <para> If the name of your sequence object does not follow this
953                 naming convention, use the
954                     <methodname>lastSequenceId()</methodname> method instead.
955                 This method takes a single string argument, naming the sequence
956                 literally. </para>
958             <example id="zend.db.adapter.write.lastinsertid.example-3">
959                 <title>Using lastSequenceId()</title>
960                 <programlisting language="php"><![CDATA[
961 $db->insert('bugs', $data);
963 // return the last value generated by sequence 'bugs_id_gen'.
964 $id = $db->lastSequenceId('bugs_id_gen');
965 ]]></programlisting>
966             </example>
968             <para> For <acronym>RDBMS</acronym> brands that don't support
969                 sequences, including MySQL, Microsoft <acronym>SQL</acronym>
970                 Server, and SQLite, the arguments to the lastInsertId() method
971                 are ignored, and the value returned is the most recent value
972                 generated for any table by INSERT operations during the current
973                 connection. For these <acronym>RDBMS</acronym> brands, the
974                 lastSequenceId() method always returns <constant>NULL</constant>
975                 . </para>
977             <note>
978                 <title>Why Not Use "SELECT MAX(id) FROM table"?</title>
979                 <para> Sometimes this query returns the most recent primary key
980                     value inserted into the table. However, this technique is
981                     not safe to use in an environment where multiple clients are
982                     inserting records to the database. It is possible, and
983                     therefore is bound to happen eventually, that another client
984                     inserts another row in the instant between the insert
985                     performed by your client application and your query for the
986                     MAX(id) value. Thus the value returned does not identify the
987                     row you inserted, it identifies the row inserted by some
988                     other client. There is no way to know when this has
989                     happened. </para>
990                 <para> Using a strong transaction isolation mode such as
991                     "repeatable read" can mitigate this risk, but some
992                         <acronym>RDBMS</acronym> brands don't support the
993                     transaction isolation required for this, or else your
994                     application may use a lower transaction isolation mode by
995                     design. </para>
996                 <para> Furthermore, using an expression like "MAX(id)+1" to
997                     generate a new value for a primary key is not safe, because
998                     two clients could do this query simultaneously, and then
999                     both use the same calculated value for their next INSERT
1000                     operation. </para>
1001                 <para> All <acronym>RDBMS</acronym> brands provide mechanisms to
1002                     generate unique values, and to return the last value
1003                     generated. These mechanisms necessarily work outside of the
1004                     scope of transaction isolation, so there is no chance of two
1005                     clients generating the same value, and there is no chance
1006                     that the value generated by another client could be reported
1007                     to your client's connection as the last value generated.
1008                 </para>
1009             </note>
1011         </sect3>
1013         <sect3 id="zend.db.adapter.write.update">
1014             <title>Updating Data</title>
1016             <para> You can update rows in a database table using the
1017                     <methodname>update()</methodname> method of an Adapter. This
1018                 method takes three arguments: the first is the name of the
1019                 table; the second is an associative array mapping columns to
1020                 change to new values to assign to these columns. </para>
1022             <para> The values in the data array are treated as string literals.
1023                 See <xref linkend="zend.db.adapter.write.insert"/> for
1024                 information on using <acronym>SQL</acronym> expressions in the
1025                 data array. </para>
1027             <para> The third argument is a string containing an
1028                     <acronym>SQL</acronym> expression that is used as criteria
1029                 for the rows to change. The values and identifiers in this
1030                 argument are not quoted or escaped. You are responsible for
1031                 ensuring that any dynamic content is interpolated into this
1032                 string safely. See <xref linkend="zend.db.adapter.quoting"/> for
1033                 methods to help you do this. </para>
1035             <para> The return value is the number of rows affected by the update
1036                 operation. </para>
1038             <example id="zend.db.adapter.write.update.example">
1039                 <title>Updating Rows</title>
1040                 <programlisting language="php"><![CDATA[
1041 $data = array(
1042     'updated_on'      => '2007-03-23',
1043     'bug_status'      => 'FIXED'
1046 $n = $db->update('bugs', $data, 'bug_id = 2');
1047 ]]></programlisting>
1048             </example>
1050             <para> If you omit the third argument, then all rows in the database
1051                 table are updated with the values specified in the data array. </para>
1053             <para> If you provide an array of strings as the third argument,
1054                 these strings are joined together as terms in an expression
1055                 separated by <constant>AND</constant> operators. </para>
1057             <example id="zend.db.adapter.write.update.example-array">
1058                 <title>Updating Rows Using an Array of Expressions</title>
1059                 <programlisting language="php"><![CDATA[
1060 $data = array(
1061     'updated_on'      => '2007-03-23',
1062     'bug_status'      => 'FIXED'
1065 $where[] = "reported_by = 'goofy'";
1066 $where[] = "bug_status = 'OPEN'";
1068 $n = $db->update('bugs', $data, $where);
1070 // Resulting SQL is:
1071 //  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
1072 //  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
1073 ]]></programlisting>
1074             </example>
1076         </sect3>
1078         <sect3 id="zend.db.adapter.write.delete">
1079             <title>Deleting Data</title>
1080             <para> You can delete rows from a database table using the
1081                     <methodname>delete()</methodname> method. This method takes
1082                 two arguments: the first is a string naming the table. </para>
1084             <para> The second argument is a string containing an
1085                     <acronym>SQL</acronym> expression that is used as criteria
1086                 for the rows to delete. The values and identifiers in this
1087                 argument are not quoted or escaped. You are responsible for
1088                 ensuring that any dynamic content is interpolated into this
1089                 string safely. See <xref linkend="zend.db.adapter.quoting"/> for
1090                 methods to help you do this. </para>
1092             <para> The return value is the number of rows affected by the delete
1093                 operation. </para>
1095             <example id="zend.db.adapter.write.delete.example">
1096                 <title>Deleting Rows</title>
1097                 <programlisting language="php"><![CDATA[
1098 $n = $db->delete('bugs', 'bug_id = 3');
1099 ]]></programlisting>
1100             </example>
1102             <para> If you omit the second argument, the result is that all rows
1103                 in the database table are deleted. </para>
1105             <para> If you provide an array of strings as the second argument,
1106                 these strings are joined together as terms in an expression
1107                 separated by <constant>AND</constant> operators. </para>
1109         </sect3>
1111     </sect2>
1113     <sect2 id="zend.db.adapter.quoting">
1115         <title>Quoting Values and Identifiers</title>
1117         <para> When you form <acronym>SQL</acronym> queries, often it is the
1118             case that you need to include the values of PHP variables in
1119                 <acronym>SQL</acronym> expressions. This is risky, because if
1120             the value in a PHP string contains certain symbols, such as the
1121             quote symbol, it could result in invalid <acronym>SQL</acronym> .
1122             For example, notice the imbalanced quote characters in the following
1123             query: <programlisting language="php"><![CDATA[
1124 $name = "O'Reilly";
1125 $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
1127 echo $sql;
1128 // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
1129 ]]></programlisting>
1130         </para>
1132         <para> Even worse is the risk that such code mistakes might be exploited
1133             deliberately by a person who is trying to manipulate the function of
1134             your web application. If they can specify the value of a
1135                 <acronym>PHP</acronym> variable through the use of an
1136                 <acronym>HTTP</acronym> parameter or other mechanism, they might
1137             be able to make your <acronym>SQL</acronym> queries do things that
1138             you didn't intend them to do, such as return data to which the
1139             person should not have privilege to read. This is a serious and
1140             widespread technique for violating application security, known as
1141             "SQL Injection" (see <ulink
1142                 url="http://en.wikipedia.org/wiki/SQL_Injection"
1143                 >http://en.wikipedia.org/wiki/SQL_Injection</ulink> ). </para>
1145         <para> The <classname>Zend_Db</classname> Adapter class provides
1146             convenient functions to help you reduce vulnerabilities to
1147                 <acronym>SQL</acronym> Injection attacks in your
1148                 <acronym>PHP</acronym> code. The solution is to escape special
1149             characters such as quotes in <acronym>PHP</acronym> values before
1150             they are interpolated into your <acronym>SQL</acronym> strings. This
1151             protects against both accidental and deliberate manipulation of
1152                 <acronym>SQL</acronym> strings by <acronym>PHP</acronym>
1153             variables that contain special characters. </para>
1155         <sect3 id="zend.db.adapter.quoting.quote">
1157             <title>Using quote()</title>
1159             <para> The <methodname>quote()</methodname> method accepts a single
1160                 argument, a scalar string value. It returns the value with
1161                 special characters escaped in a manner appropriate for the
1162                     <acronym>RDBMS</acronym> you are using, and surrounded by
1163                 string value delimiters. The standard <acronym>SQL</acronym>
1164                 string value delimiter is the single-quote ( <code>'</code> ). </para>
1166             <example id="zend.db.adapter.quoting.quote.example">
1167                 <title>Using quote()</title>
1168                 <programlisting language="php"><![CDATA[
1169 $name = $db->quote("O'Reilly");
1170 echo $name;
1171 // 'O\'Reilly'
1173 $sql = "SELECT * FROM bugs WHERE reported_by = $name";
1175 echo $sql;
1176 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1177 ]]></programlisting>
1178             </example>
1180             <para> Note that the return value of
1181                     <methodname>quote()</methodname> includes the quote
1182                 delimiters around the string. This is different from some
1183                 functions that escape special characters but do not add the
1184                 quote delimiters, for example <ulink
1185                     url="http://www.php.net/mysqli_real_escape_string"
1186                     >mysql_real_escape_string()</ulink> . </para>
1188             <para> Values may need to be quoted or not quoted according to the
1189                     <acronym>SQL</acronym> datatype context in which they are
1190                 used. For instance, in some RDBMS brands, an integer value must
1191                 not be quoted as a string if it is compared to an integer-type
1192                 column or expression. In other words, the following is an error
1193                 in some <acronym>SQL</acronym> implementations, assuming
1194                     <code>intColumn</code> has a <acronym>SQL</acronym> datatype
1195                 of <constant>INTEGER</constant>
1196                 <programlisting language="php"><![CDATA[
1197 SELECT * FROM atable WHERE intColumn = '123'
1198 ]]></programlisting>
1199             </para>
1201             <para> You can use the optional second argument to the
1202                     <methodname>quote()</methodname> method to apply quoting
1203                 selectively for the <acronym>SQL</acronym> datatype you specify. </para>
1205             <example id="zend.db.adapter.quoting.quote.example-2">
1206                 <title>Using quote() with a SQL Type</title>
1207                 <programlisting language="php"><![CDATA[
1208 $value = '1234';
1209 $sql = 'SELECT * FROM atable WHERE intColumn = '
1210      . $db->quote($value, 'INTEGER');
1211 ]]></programlisting>
1212             </example>
1214             <para> Each <classname>Zend_Db_Adapter</classname> class has encoded
1215                 the names of numeric <acronym>SQL</acronym> datatypes for the
1216                 respective brand of <acronym>RDBMS</acronym> . You can also use
1217                 the constants <constant>Zend_Db::INT_TYPE</constant> ,
1218                     <constant>Zend_Db::BIGINT_TYPE</constant> , and
1219                     <constant>Zend_Db::FLOAT_TYPE</constant> to write code in a
1220                 more <acronym>RDBMS</acronym> -independent way. </para>
1222             <para>
1223                 <classname>Zend_Db_Table</classname> specifies
1224                     <acronym>SQL</acronym> types to
1225                     <methodname>quote()</methodname> automatically when
1226                 generating <acronym>SQL</acronym> queries that reference a
1227                 table's key columns. </para>
1229         </sect3>
1231         <sect3 id="zend.db.adapter.quoting.quote-into">
1233             <title>Using quoteInto()</title>
1235             <para> The most typical usage of quoting is to interpolate a
1236                     <acronym>PHP</acronym> variable into a
1237                     <acronym>SQL</acronym> expression or statement. You can use
1238                 the <methodname>quoteInto()</methodname> method to do this in
1239                 one step. This method takes two arguments: the first argument is
1240                 a string containing a placeholder symbol ( <code>?</code> ), and
1241                 the second argument is a value or <acronym>PHP</acronym>
1242                 variable that should be substituted for that placeholder. </para>
1244             <para> The placeholder symbol is the same symbol used by many
1245                     <acronym>RDBMS</acronym> brands for positional parameters,
1246                 but the <methodname>quoteInto()</methodname> method only
1247                 emulates query parameters. The method simply interpolates the
1248                 value into the string, escapes special characters, and applies
1249                 quotes around it. True query parameters maintain the separation
1250                 between the <acronym>SQL</acronym> string and the parameters as
1251                 the statement is parsed in the <acronym>RDBMS</acronym> server. </para>
1253             <example id="zend.db.adapter.quoting.quote-into.example">
1254                 <title>Using quoteInto()</title>
1255                 <programlisting language="php"><![CDATA[
1256 $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
1258 echo $sql;
1259 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1260 ]]></programlisting>
1261             </example>
1263             <para> You can use the optional third parameter of
1264                     <methodname>quoteInto()</methodname> to specify the
1265                     <acronym>SQL</acronym> datatype. Numeric datatypes are not
1266                 quoted, and other types are quoted. </para>
1268             <example id="zend.db.adapter.quoting.quote-into.example-2">
1269                 <title>Using quoteInto() with a SQL Type</title>
1270                 <programlisting language="php"><![CDATA[
1271 $sql = $db
1272     ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
1274 echo $sql;
1275 // SELECT * FROM bugs WHERE reported_by = 1234
1276 ]]></programlisting>
1277             </example>
1279         </sect3>
1280         <sect3 id="zend.db.adapter.quoting.quote-identifier">
1282             <title>Using quoteIdentifier()</title>
1284             <para> Values are not the only part of <acronym>SQL</acronym> syntax
1285                 that might need to be variable. If you use
1286                     <acronym>PHP</acronym> variables to name tables, columns, or
1287                 other identifiers in your <acronym>SQL</acronym> statements, you
1288                 might need to quote these strings too. By default,
1289                     <acronym>SQL</acronym> identifiers have syntax rules like
1290                     <acronym>PHP</acronym> and most other programming languages.
1291                 For example, identifiers should not contain spaces, certain
1292                 punctuation or special characters, or international characters.
1293                 Also certain words are reserved for <acronym>SQL</acronym>
1294                 syntax, and should not be used as identifiers. </para>
1296             <para> However, <acronym>SQL</acronym> has a feature called
1297                     <emphasis>delimited identifiers</emphasis> , which allows
1298                 broader choices for the spelling of identifiers. If you enclose
1299                 a <acronym>SQL</acronym> identifier in the proper types of
1300                 quotes, you can use identifiers with spellings that would be
1301                 invalid without the quotes. Delimited identifiers can contain
1302                 spaces, punctuation, or international characters. You can also
1303                 use <acronym>SQL</acronym> reserved words if you enclose them in
1304                 identifier delimiters. </para>
1306             <para> The <methodname>quoteIdentifier()</methodname> method works
1307                 like <methodname>quote()</methodname> , but it applies the
1308                 identifier delimiter characters to the string according to the
1309                 type of Adapter you use. For example, standard
1310                     <acronym>SQL</acronym> uses double-quotes ( <code>"</code> )
1311                 for identifier delimiters, and most <acronym>RDBMS</acronym>
1312                 brands use that symbol. MySQL uses back-quotes ( <code>`</code>
1313                 ) by default. The <methodname>quoteIdentifier()</methodname>
1314                 method also escapes special characters within the string
1315                 argument. </para>
1317             <example id="zend.db.adapter.quoting.quote-identifier.example">
1318                 <title>Using quoteIdentifier()</title>
1319                 <programlisting language="php"><![CDATA[
1320 // we might have a table name that is an SQL reserved word
1321 $tableName = $db->quoteIdentifier("order");
1323 $sql = "SELECT * FROM $tableName";
1325 echo $sql
1326 // SELECT * FROM "order"
1327 ]]></programlisting>
1328             </example>
1330             <para>
1331                 <acronym>SQL</acronym> delimited identifiers are case-sensitive,
1332                 unlike unquoted identifiers. Therefore, if you use delimited
1333                 identifiers, you must use the spelling of the identifier exactly
1334                 as it is stored in your schema, including the case of the
1335                 letters. </para>
1337             <para> In most cases where <acronym>SQL</acronym> is generated
1338                 within <classname>Zend_Db</classname> classes, the default is
1339                 that all identifiers are delimited automatically. You can change
1340                 this behavior with the option
1341                     <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> .
1342                 Specify this when instantiating the Adapter. See <xref
1343                     linkend="zend.db.adapter.connecting.parameters.example2"/> . </para>
1345         </sect3>
1347     </sect2>
1349     <sect2 id="zend.db.adapter.transactions">
1351         <title>Controlling Database Transactions</title>
1353         <para> Databases define transactions as logical units of work that can
1354             be committed or rolled back as a single change, even if they operate
1355             on multiple tables. All queries to a database are executed within
1356             the context of a transaction, even if the database driver manages
1357             them implicitly. This is called <emphasis>auto-commit</emphasis>
1358             mode, in which the database driver creates a transaction for every
1359             statement you execute, and commits that transaction after your
1360                 <acronym>SQL</acronym> statement has been executed. By default,
1361             all <classname>Zend_Db</classname> Adapter classes operate in
1362             auto-commit mode. </para>
1364         <para> Alternatively, you can specify the beginning and resolution of a
1365             transaction, and thus control how many <acronym>SQL</acronym>
1366             queries are included in a single group that is committed (or rolled
1367             back) as a single operation. Use the
1368                 <methodname>beginTransaction()</methodname> method to initiate a
1369             transaction. Subsequent <acronym>SQL</acronym> statements are
1370             executed in the context of the same transaction until you resolve it
1371             explicitly. </para>
1373         <para> To resolve the transaction, use either the
1374                 <methodname>commit()</methodname> or
1375                 <methodname>rollBack()</methodname> methods. The
1376                 <methodname>commit()</methodname> method marks changes made
1377             during your transaction as committed, which means the effects of
1378             these changes are shown in queries run in other transactions. </para>
1380         <para> The <methodname>rollBack()</methodname> method does the opposite:
1381             it discards the changes made during your transaction. The changes
1382             are effectively undone, and the state of the data returns to how it
1383             was before you began your transaction. However, rolling back your
1384             transaction has no effect on changes made by other transactions
1385             running concurrently. </para>
1387         <para> After you resolve this transaction,
1388                 <classname>Zend_Db_Adapter</classname> returns to auto-commit
1389             mode until you call <methodname>beginTransaction()</methodname>
1390             again. </para>
1392         <example id="zend.db.adapter.transactions.example">
1393             <title>Managing a Transaction to Ensure Consistency</title>
1394             <programlisting language="php"><![CDATA[
1395 // Start a transaction explicitly.
1396 $db->beginTransaction();
1398 try {
1399     // Attempt to execute one or more queries:
1400     $db->query(...);
1401     $db->query(...);
1402     $db->query(...);
1404     // If all succeed, commit the transaction and all changes
1405     // are committed at once.
1406     $db->commit();
1408 } catch (Exception $e) {
1409     // If any of the queries failed and threw an exception,
1410     // we want to roll back the whole transaction, reversing
1411     // changes made in the transaction, even those that succeeded.
1412     // Thus all changes are committed together, or none are.
1413     $db->rollBack();
1414     echo $e->getMessage();
1416 ]]></programlisting>
1417         </example>
1419     </sect2>
1421     <sect2 id="zend.db.adapter.list-describe">
1423         <title>Listing and Describing Tables</title>
1425         <para> The <methodname>listTables()</methodname> method returns an array
1426             of strings, naming all tables in the current database. </para>
1428         <para> The <methodname>describeTable()</methodname> method returns an
1429             associative array of metadata about a table. Specify the name of the
1430             table as a string in the first argument to this method. The second
1431             argument is optional, and names the schema in which the table
1432             exists. </para>
1434         <para> The keys of the associative array returned are the column names
1435             of the table. The value corresponding to each column is also an
1436             associative array, with the following keys and values: </para>
1438         <table frame="all" cellpadding="5"
1439             id="zend.db.adapter.list-describe.metadata">
1440             <title>Metadata Fields Returned by describeTable()</title>
1441             <tgroup cols="3" align="left" colsep="1" rowsep="1">
1442                 <thead>
1443                     <row>
1444                         <entry>Key</entry>
1445                         <entry>Type</entry>
1446                         <entry>Description</entry>
1447                     </row>
1448                 </thead>
1449                 <tbody>
1450                     <row>
1451                         <entry>
1452                             <constant>SCHEMA_NAME</constant>
1453                         </entry>
1454                         <entry>(string)</entry>
1455                         <entry>Name of the database schema in which this table
1456                             exists.</entry>
1457                     </row>
1458                     <row>
1459                         <entry>
1460                             <constant>TABLE_NAME</constant>
1461                         </entry>
1462                         <entry>(string)</entry>
1463                         <entry>Name of the table to which this column
1464                             belongs.</entry>
1465                     </row>
1466                     <row>
1467                         <entry>
1468                             <constant>COLUMN_NAME</constant>
1469                         </entry>
1470                         <entry>(string)</entry>
1471                         <entry>Name of the column.</entry>
1472                     </row>
1473                     <row>
1474                         <entry>
1475                             <constant>COLUMN_POSITION</constant>
1476                         </entry>
1477                         <entry>(integer)</entry>
1478                         <entry>Ordinal position of the column in the
1479                             table.</entry>
1480                     </row>
1481                     <row>
1482                         <entry>
1483                             <constant>DATA_TYPE</constant>
1484                         </entry>
1485                         <entry>(string)</entry>
1486                         <entry>RDBMS name of the datatype of the column.</entry>
1487                     </row>
1488                     <row>
1489                         <entry>
1490                             <constant>DEFAULT</constant>
1491                         </entry>
1492                         <entry>(string)</entry>
1493                         <entry>Default value for the column, if any.</entry>
1494                     </row>
1495                     <row>
1496                         <entry>
1497                             <constant>NULLABLE</constant>
1498                         </entry>
1499                         <entry>(boolean)</entry>
1500                         <entry> <constant>TRUE</constant> if the column accepts
1501                             <acronym>SQL</acronym>  <constant>NULL</constant>s, <constant>FALSE</constant> if the
1502                             column has a <constant>NOT</constant> <constant>NULL</constant> constraint. </entry>
1503                     </row>
1504                     <row>
1505                         <entry>
1506                             <constant>LENGTH</constant>
1507                         </entry>
1508                         <entry>(integer)</entry>
1509                         <entry> Length or size of the column as reported by the
1510                                 <acronym>RDBMS</acronym> . </entry>
1511                     </row>
1512                     <row>
1513                         <entry>
1514                             <constant>SCALE</constant>
1515                         </entry>
1516                         <entry>(integer)</entry>
1517                         <entry> Scale of <acronym>SQL</acronym> NUMERIC or
1518                                 <constant>DECIMAL</constant> type. </entry>
1519                     </row>
1520                     <row>
1521                         <entry>
1522                             <constant>PRECISION</constant>
1523                         </entry>
1524                         <entry>(integer)</entry>
1525                         <entry> Precision of <acronym>SQL</acronym> NUMERIC or
1526                                 <constant>DECIMAL</constant> type. </entry>
1527                     </row>
1528                     <row>
1529                         <entry>
1530                             <constant>UNSIGNED</constant>
1531                         </entry>
1532                         <entry>(boolean)</entry>
1533                         <entry> <constant>TRUE</constant> if an integer-based type is reported as
1534                                 <constant>UNSIGNED</constant> . </entry>
1535                     </row>
1536                     <row>
1537                         <entry>
1538                             <constant>PRIMARY</constant>
1539                         </entry>
1540                         <entry>(boolean)</entry>
1541                         <entry><constant>TRUE</constant> if the column is part of the primary key of
1542                             this table.</entry>
1543                     </row>
1544                     <row>
1545                         <entry>
1546                             <constant>PRIMARY_POSITION</constant>
1547                         </entry>
1548                         <entry>(integer)</entry>
1549                         <entry>Ordinal position (1-based) of the column in the
1550                             primary key.</entry>
1551                     </row>
1552                     <row>
1553                         <entry>
1554                             <constant>IDENTITY</constant>
1555                         </entry>
1556                         <entry>(boolean)</entry>
1557                         <entry><constant>TRUE</constant> if the column uses an auto-generated
1558                             value.</entry>
1559                     </row>
1560                 </tbody>
1561             </tgroup>
1562         </table>
1564         <note>
1565             <title>How the IDENTITY Metadata Field Relates to Specific
1566                 RDBMSs</title>
1567             <para> The IDENTITY metadata field was chosen as an 'idiomatic' term
1568                 to represent a relation to surrogate keys. This field can be
1569                 commonly known by the following values:- </para>
1570             <itemizedlist>
1571                 <listitem>
1572                     <para>
1573                         <constant>IDENTITY</constant> - DB2, MSSQL </para>
1574                 </listitem>
1575                 <listitem>
1576                     <para>
1577                         <constant>AUTO_INCREMENT</constant> - MySQL </para>
1578                 </listitem>
1579                 <listitem>
1580                     <para>
1581                         <constant>SERIAL</constant> - PostgreSQL </para>
1582                 </listitem>
1583                 <listitem>
1584                     <para>
1585                         <constant>SEQUENCE</constant> - Oracle </para>
1586                 </listitem>
1587             </itemizedlist>
1588         </note>
1590         <para> If no table exists matching the table name and optional schema
1591             name specified, then <methodname>describeTable()</methodname>
1592             returns an empty array. </para>
1594     </sect2>
1596     <sect2 id="zend.db.adapter.closing">
1598         <title>Closing a Connection</title>
1600         <para> Normally it is not necessary to close a database connection.
1601                 <acronym>PHP</acronym> automatically cleans up all resources and
1602             the end of a request. Database extensions are designed to close the
1603             connection as the reference to the resource object is cleaned up. </para>
1605         <para> However, if you have a long-duration <acronym>PHP</acronym>
1606             script that initiates many database connections, you might need to
1607             close the connection, to avoid exhausting the capacity of your
1608                 <acronym>RDBMS</acronym> server. You can use the Adapter's
1609                 <methodname>closeConnection()</methodname> method to explicitly
1610             close the underlying database connection. </para>
1612         <para> Since release 1.7.2, you could check you are currently connected
1613             to the <acronym>RDBMS</acronym> server with the method
1614                 <methodname>isConnected()</methodname> . This means that a
1615             connection resource has been initiated and wasn't closed. This
1616             function is not currently able to test for example a server side
1617             closing of the connection. This is internally use to close the
1618             connection. It allow you to close the connection multiple times
1619             without errors. It was already the case before 1.7.2 for
1620                 <acronym>PDO</acronym> adapters but not for the others. </para>
1622         <example id="zend.db.adapter.closing.example">
1623             <title>Closing a Database Connection</title>
1624             <programlisting language="php"><![CDATA[
1625 $db->closeConnection();
1626 ]]></programlisting>
1627         </example>
1629         <note>
1630             <title>Does Zend_Db Support Persistent Connections?</title>
1631             <para> Yes, persistence is supported through the addition of the
1632                 <property>persistent</property> flag set to true in the
1633                 configuration (not driver_configuration) of an adapter in
1634                     <classname>Zend_Db</classname> . </para>
1636             <example id="zend.db.adapter.connecting.persistence.example">
1637                 <title>Using the Persitence Flag with the Oracle Adapter</title>
1638                 <programlisting language="php"><![CDATA[
1639 $db = Zend_Db::factory('Oracle', array(
1640     'host'       => '127.0.0.1',
1641     'username'   => 'webuser',
1642     'password'   => 'xxxxxxxx',
1643     'dbname'     => 'test',
1644     'persistent' => true
1646 ]]></programlisting>
1647             </example>
1649             <para> Please note that using persistent connections can cause an
1650                 excess of idle connections on the <acronym>RDBMS</acronym>
1651                 server, which causes more problems than any performance gain you
1652                 might achieve by reducing the overhead of making connections. </para>
1653             <para> Database connections have state. That is, some objects in the
1654                     <acronym>RDBMS</acronym> server exist in session scope.
1655                 Examples are locks, user variables, temporary tables, and
1656                 information about the most recently executed query, such as rows
1657                 affected, and last generated id value. If you use persistent
1658                 connections, your application could access invalid or privileged
1659                 data that were created in a previous <acronym>PHP</acronym>
1660                 request. </para>
1661             <para> Currently, only Oracle, DB2, and the <acronym>PDO</acronym>
1662                 adapters (where specified by <acronym>PHP</acronym> ) support
1663                 persistence in <classname>Zend_Db</classname> . </para>
1664         </note>
1666     </sect2>
1668     <sect2 id="zend.db.adapter.other-statements">
1670         <title>Running Other Database Statements</title>
1672         <para> There might be cases in which you need to access the connection
1673             object directly, as provided by the <acronym>PHP</acronym> database
1674             extension. Some of these extensions may offer features that are not
1675             surfaced by methods of
1676                 <classname>Zend_Db_Adapter_Abstract</classname> . </para>
1678         <para> For example, all <acronym>SQL</acronym> statements run by
1679                 <classname>Zend_Db</classname> are prepared, then executed.
1680             However, some database features are incompatible with prepared
1681             statements. DDL statements like CREATE and ALTER cannot be prepared
1682             in MySQL. Also, <acronym>SQL</acronym> statements don't benefit from
1683             the <ulink
1684                 url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html"
1685                 >MySQL Query Cache</ulink> , prior to MySQL 5.1.17. </para>
1687         <para> Most <acronym>PHP</acronym> database extensions provide a method
1688             to execute <acronym>SQL</acronym> statements without preparing them.
1689             For example, in <acronym>PDO</acronym> , this method is
1690                 <methodname>exec()</methodname> . You can access the connection
1691             object in the <acronym>PHP</acronym> extension directly using
1692             getConnection(). </para>
1694         <example id="zend.db.adapter.other-statements.example">
1695             <title>Running a Non-Prepared Statement in a PDO Adapter</title>
1696             <programlisting language="php"><![CDATA[
1697 $result = $db->getConnection()->exec('DROP TABLE bugs');
1698 ]]></programlisting>
1699         </example>
1701         <para> Similarly, you can access other methods or properties that are
1702             specific to <acronym>PHP</acronym> database extensions. Be aware,
1703             though, that by doing this you might constrain your application to
1704             the interface provided by the extension for a specific brand of
1705                 <acronym>RDBMS</acronym> . </para>
1707         <para> In future versions of <classname>Zend_Db</classname> , there will
1708             be opportunities to add method entry points for functionality that
1709             is common to the supported <acronym>PHP</acronym> database
1710             extensions. This will not affect backward compatibility. </para>
1712     </sect2>
1714     <sect2 id="zend.db.adapter.server-version">
1715         <title>Retrieving Server Version</title>
1717         <para> Since release 1.7.2, you could retrieve the server version in
1718                 <acronym>PHP</acronym> syntax style to be able to use
1719                 <methodname>version_compare()</methodname> . If the information
1720             isn't available, you will receive <constant>NULL</constant> . </para>
1722         <example id="zend.db.adapter.server-version.example">
1723             <title>Verifying server version before running a query</title>
1724             <programlisting language="php"><![CDATA[
1725 $version = $db->getServerVersion();
1726 if (!is_null($version)) {
1727     if (version_compare($version, '5.0.0', '>=')) {
1728         // do something
1729     } else {
1730         // do something else
1731     }
1732 } else {
1733     // impossible to read server version
1735 ]]></programlisting>
1736         </example>
1737     </sect2>
1739     <sect2 id="zend.db.adapter.adapter-notes">
1741         <title>Notes on Specific Adapters</title>
1743         <para> This section lists differences between the Adapter classes of
1744             which you should be aware. </para>
1746         <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
1747             <title>IBM DB2</title>
1748             <itemizedlist>
1749                 <listitem>
1750                     <para> Specify this Adapter to the factory() method with the
1751                         name 'Db2'. </para>
1752                 </listitem>
1753                 <listitem>
1754                     <para> This Adapter uses the <acronym>PHP</acronym>
1755                         extension ibm_db2. </para>
1756                 </listitem>
1757                 <listitem>
1758                     <para> IBM DB2 supports both sequences and auto-incrementing
1759                         keys. Therefore the arguments to
1760                             <methodname>lastInsertId()</methodname> are
1761                         optional. If you give no arguments, the Adapter returns
1762                         the last value generated for an auto-increment key. If
1763                         you give arguments, the Adapter returns the last value
1764                         generated by the sequence named according to the
1765                         convention ' <emphasis>table</emphasis> _
1766                             <emphasis>column</emphasis> _seq'. </para>
1767                 </listitem>
1768             </itemizedlist>
1769         </sect3>
1771         <sect3 id="zend.db.adapter.adapter-notes.mysqli">
1772             <title>MySQLi</title>
1773             <itemizedlist>
1774                 <listitem>
1775                     <para> Specify this Adapter to the
1776                             <methodname>factory()</methodname> method with the
1777                         name 'Mysqli'. </para>
1778                 </listitem>
1779                 <listitem>
1780                     <para> This Adapter utilizes the <acronym>PHP</acronym>
1781                         extension mysqli. </para>
1782                 </listitem>
1783                 <listitem>
1784                     <para> MySQL does not support sequences, so
1785                             <methodname>lastInsertId()</methodname> ignores its
1786                         arguments and always returns the last value generated
1787                         for an auto-increment key. The
1788                             <methodname>lastSequenceId()</methodname> method
1789                         returns <constant>NULL</constant> . </para>
1790                 </listitem>
1791             </itemizedlist>
1792         </sect3>
1794         <sect3 id="zend.db.adapter.adapter-notes.oracle">
1795             <title>Oracle</title>
1796             <itemizedlist>
1797                 <listitem>
1798                     <para> Specify this Adapter to the
1799                             <methodname>factory()</methodname> method with the
1800                         name 'Oracle'. </para>
1801                 </listitem>
1802                 <listitem>
1803                     <para> This Adapter uses the <acronym>PHP</acronym>
1804                         extension oci8. </para>
1805                 </listitem>
1806                 <listitem>
1807                     <para> Oracle does not support auto-incrementing keys, so
1808                         you should specify the name of a sequence to
1809                             <methodname>lastInsertId()</methodname> or
1810                             <methodname>lastSequenceId()</methodname> . </para>
1811                 </listitem>
1812                 <listitem>
1813                     <para> The Oracle extension does not support positional
1814                         parameters. You must use named parameters. </para>
1815                 </listitem>
1816                 <listitem>
1817                     <para> Currently the
1818                             <constant>Zend_Db::CASE_FOLDING</constant> option is
1819                         not supported by the Oracle adapter. To use this option
1820                         with Oracle, you must use the <acronym>PDO</acronym> OCI
1821                         adapter. </para>
1822                 </listitem>
1823                 <listitem>
1824                     <para> By default, LOB fields are returned as OCI-Lob
1825                         objects. You could retrieve them as string for all
1826                         requests by using driver options
1827                             <code>'lob_as_string'</code> or for particular
1828                         request by using
1829                             <methodname>setLobAsString(boolean)</methodname> on
1830                         adapter or on statement. </para>
1831                 </listitem>
1832             </itemizedlist>
1833         </sect3>
1835         <sect3 id="zend.db.adapter.adapter-notes.sqlsrv">
1836             <title>Microsoft SQL Server</title>
1837             <itemizedlist>
1838                 <listitem>
1839                     <para> Specify this Adapter to the
1840                             <methodname>factory()</methodname> method with the
1841                         name 'Sqlsrv'. </para>
1842                 </listitem>
1843                 <listitem>
1844                     <para> This Adapter uses the <acronym>PHP</acronym>
1845                         extension sqlsrv </para>
1846                 </listitem>
1847                 <listitem>
1848                     <para> Microsoft <acronym>SQL</acronym> Server does not
1849                         support sequences, so
1850                             <methodname>lastInsertId()</methodname> ignores
1851                         primary key argument and returns the last value
1852                         generated for an auto-increment key if a table name is
1853                         specified or a last insert query returned id. The
1854                             <methodname>lastSequenceId()</methodname> method
1855                         returns <constant>NULL</constant> . </para>
1856                 </listitem>
1857                 <listitem>
1858                     <para>
1859                         <classname>Zend_Db_Adapter_Sqlsrv</classname> sets
1860                             <constant>QUOTED_IDENTIFIER ON</constant>
1861                         immediately after connecting to a <acronym>SQL</acronym>
1862                         Server database. This makes the driver use the standard
1863                             <acronym>SQL</acronym> identifier delimiter symbol (
1864                             <emphasis>"</emphasis> ) instead of the proprietary
1865                         square-brackets syntax <acronym>SQL</acronym> Server
1866                         uses for delimiting identifiers. </para>
1867                 </listitem>
1868                 <listitem>
1869                     <para> You can specify <property>driver_options</property>
1870                         as a key in the options array. The value can be a
1871                         anything from here <ulink
1872                             url="http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx"
1873                             >http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx</ulink>
1874                         . </para>
1875                 </listitem>
1876                 <listitem>
1877                     <para> You can use
1878                             <methodname>setTransactionIsolationLevel()</methodname>
1879                         to set isolation level for current connection. The value
1880                         can be <constant>SQLSRV_TXN_READ_UNCOMMITTED</constant>
1881                         , <constant>SQLSRV_TXN_READ_COMMITTED</constant> ,
1882                             <constant>SQLSRV_TXN_REPEATABLE_READ</constant> ,
1883                             <constant>SQLSRV_TXN_SNAPSHOT</constant> or
1884                             <constant>SQLSRV_TXN_SERIALIZABLE</constant> .
1885                     </para>
1886                 </listitem>
1887                 <listitem>
1888                     <para> As of Zend Framework 1.9, the minimal supported build
1889                         of the <acronym>PHP</acronym>
1890                         <acronym>SQL</acronym> Server extension from Microsoft
1891                         is 1.0.1924.0. and the <acronym>MSSQL</acronym> Server
1892                         Native Client version 9.00.3042.00. </para>
1893                 </listitem>
1894             </itemizedlist>
1895         </sect3>
1897         <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
1898             <title>PDO for IBM DB2 and Informix Dynamic Server (IDS)</title>
1899             <itemizedlist>
1900                 <listitem>
1901                     <para> Specify this Adapter to the
1902                             <methodname>factory()</methodname> method with the
1903                         name 'Pdo_Ibm'. </para>
1904                 </listitem>
1905                 <listitem>
1906                     <para> This Adapter uses the <acronym>PHP</acronym>
1907                         extensions pdo and pdo_ibm. </para>
1908                 </listitem>
1909                 <listitem>
1910                     <para> You must use at least <acronym>PDO</acronym> _IBM
1911                         extension version 1.2.2. If you have an earlier version
1912                         of this extension, you must upgrade the
1913                             <acronym>PDO</acronym> _IBM extension from
1914                             <acronym>PECL</acronym> . </para>
1915                 </listitem>
1916             </itemizedlist>
1917         </sect3>
1919         <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
1920             <title>PDO Microsoft SQL Server</title>
1921             <itemizedlist>
1922                 <listitem>
1923                     <para> Specify this Adapter to the
1924                             <methodname>factory()</methodname> method with the
1925                         name 'Pdo_Mssql'. </para>
1926                 </listitem>
1927                 <listitem>
1928                     <para> This Adapter uses the <acronym>PHP</acronym>
1929                         extensions pdo and pdo_mssql. </para>
1930                 </listitem>
1931                 <listitem>
1932                     <para> Microsoft <acronym>SQL</acronym> Server does not
1933                         support sequences, so
1934                             <methodname>lastInsertId()</methodname> ignores its
1935                         arguments and always returns the last value generated
1936                         for an auto-increment key. The
1937                             <methodname>lastSequenceId()</methodname> method
1938                         returns <constant>NULL</constant> . </para>
1939                 </listitem>
1940                 <listitem>
1941                     <para> If you are working with unicode strings in an
1942                         encoding other than UCS-2 (such as UTF-8), you may have
1943                         to perform a conversion in your application code or
1944                         store the data in a binary column. Please refer to
1945                             <ulink url="http://support.microsoft.com/kb/232580"
1946                             >Microsoft's Knowledge Base</ulink> for more
1947                         information. </para>
1948                 </listitem>
1949                 <listitem>
1950                     <para>
1951                         <classname>Zend_Db_Adapter_Pdo_Mssql</classname> sets
1952                             <constant>QUOTED_IDENTIFIER ON</constant>
1953                         immediately after connecting to a <acronym>SQL</acronym>
1954                         Server database. This makes the driver use the standard
1955                             <acronym>SQL</acronym> identifier delimiter symbol (
1956                             <code>"</code> ) instead of the proprietary
1957                         square-brackets syntax <acronym>SQL</acronym> Server
1958                         uses for delimiting identifiers. </para>
1959                 </listitem>
1960                 <listitem>
1961                     <para> You can specify <code>pdoType</code> as a key in the
1962                         options array. The value can be "mssql" (the default),
1963                         "dblib", "freetds", or "sybase". This option affects the
1964                         DSN prefix the adapter uses when constructing the DSN
1965                         string. Both "freetds" and "sybase" imply a prefix of
1966                         "sybase:", which is used for the <ulink
1967                             url="http://www.freetds.org/">FreeTDS</ulink> set of
1968                         libraries. See also <ulink
1969                             url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php"
1970                             >
1971                             http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>
1972                         for more information on the DSN prefixes used in this
1973                         driver. </para>
1974                 </listitem>
1975             </itemizedlist>
1976         </sect3>
1978         <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
1979             <title>PDO MySQL</title>
1980             <itemizedlist>
1981                 <listitem>
1982                     <para> Specify this Adapter to the
1983                             <methodname>factory()</methodname> method with the
1984                         name 'Pdo_Mysql'. </para>
1985                 </listitem>
1986                 <listitem>
1987                     <para> This Adapter uses the <acronym>PHP</acronym>
1988                         extensions pdo and pdo_mysql. </para>
1989                 </listitem>
1990                 <listitem>
1991                     <para> MySQL does not support sequences, so
1992                             <methodname>lastInsertId()</methodname> ignores its
1993                         arguments and always returns the last value generated
1994                         for an auto-increment key. The
1995                             <methodname>lastSequenceId()</methodname> method
1996                         returns <constant>NULL</constant> . </para>
1997                 </listitem>
1998             </itemizedlist>
1999         </sect3>
2001         <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
2002             <title>PDO Oracle</title>
2003             <itemizedlist>
2004                 <listitem>
2005                     <para> Specify this Adapter to the
2006                             <methodname>factory()</methodname> method with the
2007                         name 'Pdo_Oci'. </para>
2008                 </listitem>
2009                 <listitem>
2010                     <para> This Adapter uses the <acronym>PHP</acronym>
2011                         extensions pdo and pdo_oci. </para>
2012                 </listitem>
2013                 <listitem>
2014                     <para> Oracle does not support auto-incrementing keys, so
2015                         you should specify the name of a sequence to
2016                             <methodname>lastInsertId()</methodname> or
2017                             <methodname>lastSequenceId()</methodname> . </para>
2018                 </listitem>
2019             </itemizedlist>
2020         </sect3>
2022         <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
2023             <title>PDO PostgreSQL</title>
2024             <itemizedlist>
2025                 <listitem>
2026                     <para> Specify this Adapter to the
2027                             <methodname>factory()</methodname> method with the
2028                         name 'Pdo_Pgsql'. </para>
2029                 </listitem>
2030                 <listitem>
2031                     <para> This Adapter uses the <acronym>PHP</acronym>
2032                         extensions pdo and pdo_pgsql. </para>
2033                 </listitem>
2034                 <listitem>
2035                     <para> PostgreSQL supports both sequences and
2036                         auto-incrementing keys. Therefore the arguments to
2037                             <methodname>lastInsertId()</methodname> are
2038                         optional. If you give no arguments, the Adapter returns
2039                         the last value generated for an auto-increment key. If
2040                         you give arguments, the Adapter returns the last value
2041                         generated by the sequence named according to the
2042                         convention ' <emphasis>table</emphasis> _
2043                             <emphasis>column</emphasis> _seq'. </para>
2044                 </listitem>
2045             </itemizedlist>
2046         </sect3>
2048         <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
2049             <title>PDO SQLite</title>
2050             <itemizedlist>
2051                 <listitem>
2052                     <para> Specify this Adapter to the
2053                             <methodname>factory()</methodname> method with the
2054                         name 'Pdo_Sqlite'. </para>
2055                 </listitem>
2056                 <listitem>
2057                     <para> This Adapter uses the <acronym>PHP</acronym>
2058                         extensions pdo and pdo_sqlite. </para>
2059                 </listitem>
2060                 <listitem>
2061                     <para> SQLite does not support sequences, so
2062                             <methodname>lastInsertId()</methodname> ignores its
2063                         arguments and always returns the last value generated
2064                         for an auto-increment key. The
2065                             <methodname>lastSequenceId()</methodname> method
2066                         returns <constant>NULL</constant> . </para>
2067                 </listitem>
2068                 <listitem>
2069                     <para> To connect to an SQLite2 database, specify
2070                             <code>'sqlite2'=>true</code> in the array of
2071                         parameters when creating an instance of the
2072                             <classname>Pdo_Sqlite</classname> Adapter. </para>
2073                 </listitem>
2074                 <listitem>
2075                     <para> To connect to an in-memory SQLite database, specify
2076                             <code>'dbname'=>':memory:'</code> in the array of
2077                         parameters when creating an instance of the
2078                             <classname>Pdo_Sqlite</classname> Adapter. </para>
2079                 </listitem>
2080                 <listitem>
2081                     <para> Older versions of the SQLite driver for
2082                             <acronym>PHP</acronym> do not seem to support the
2083                         PRAGMA commands necessary to ensure that short column
2084                         names are used in result sets. If you have problems that
2085                         your result sets are returned with keys of the form
2086                         "tablename.columnname" when you do a join query, then
2087                         you should upgrade to the current version of
2088                             <acronym>PHP</acronym> . </para>
2089                 </listitem>
2090             </itemizedlist>
2091         </sect3>
2093         <sect3 id="zend.db.adapter.adapter-notes.firebird">
2094             <title>Firebird/Interbase</title>
2095             <itemizedlist>
2096                 <listitem>
2097                     <para> This Adapter uses the <acronym>PHP</acronym>
2098                         extension php_interbase. </para>
2099                 </listitem>
2100                 <listitem>
2101                     <para> Firebird/interbase does not support auto-incrementing
2102                         keys, so you should specify the name of a sequence to
2103                             <methodname>lastInsertId()</methodname> or
2104                             <methodname>lastSequenceId()</methodname> . </para>
2105                 </listitem>
2106                 <listitem>
2107                     <para> Currently the
2108                             <constant>Zend_Db::CASE_FOLDING</constant> option is
2109                         not supported by the Firebird/interbase adapter.
2110                         Unquoted identifiers are automatically returned in upper
2111                         case. </para>
2112                 </listitem>
2114                 <listitem>
2115                     <para> Adapter name is
2116                             <classname>ZendX_Db_Adapter_Firebird</classname> . </para>
2117                     <para> Remember to use the param adapterNamespace with value
2118                             <classname>ZendX_Db_Adapter</classname> . </para>
2119                     <para> We recommend to update the gds32.dll (or linux
2120                         equivalent) bundled with php, to the same version of the
2121                         server. For Firebird the equivalent gds32.dll is
2122                         fbclient.dll. </para>
2123                     <para> By default all identifiers (tables names, fields) are
2124                         returned in upper case. </para>
2125                 </listitem>
2126             </itemizedlist>
2127         </sect3>
2129     </sect2>
2131 </sect1>