| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 20115 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.db.adapter">
- <title>Zend_Db_Adapter</title>
- <para>
- <classname>Zend_Db</classname> y sus clases relacionadas proporcionan
- una interfaz simple de base de datos <acronym>SQL</acronym> para Zend
- Framework. El <classname>Zend_Db_Adapter</classname> es la clase base
- que se utiliza para conectar su aplicación <acronym>PHP</acronym> A una
- base de datos ( <acronym>RDBMS</acronym> ). Existen diferentes clases
- Adapters(Adaptador) para cada tipo de base de datos (
- <acronym>RDBMS</acronym> ). </para>
- <para> Las clases Adapters de <classname>Zend_Db</classname> crean un puente
- entre las extensiones de base de datos de <acronym>PHP</acronym> hacia
- una interfaz común, para ayudarle a escribir aplicaciones
- <acronym>PHP</acronym> una sola vez y poder desplegar múltiples
- tipos de base de datos ( <acronym>RDBMS</acronym> ) con muy poco
- esfuerzo. </para>
- <para> La Interfaz de la clase adaptador (adapter) es similar a la intefaz
- de la extensión <ulink url="http://www.php.net/pdo">PHP Data
- Objects</ulink> . <classname>Zend_Db</classname> proporciona clases
- Adaptadoras para los drivers <acronym>PDO</acronym> de los siguientes
- tipos de <acronym>RDBMS</acronym> : </para>
- <itemizedlist>
- <listitem>
- <para> IBM DB2 e Informix Dynamic Server (IDS), usando la extensión
- <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
- </para>
- </listitem>
- <listitem>
- <para> MySQL, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-mysql"> pdo_mysql </ulink>
- </para>
- </listitem>
- <listitem>
- <para> Microsoft SQL Server, usando la extensión
- <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-mssql"> pdo_mssql </ulink>
- </para>
- </listitem>
- <listitem>
- <para> Oracle, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
- </para>
- </listitem>
- <listitem>
- <para> PostgreSQL, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-pgsql"> pdo_pgsql </ulink>
- </para>
- </listitem>
- <listitem>
- <para> SQLite, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-sqlite"> pdo_sqlite </ulink>
- </para>
- </listitem>
- </itemizedlist>
- <para> Ademas, <classname>Zend_Db</classname> proporciona clases Adaptadoras
- que utilizan las extensiones de base de datos de <acronym>PHP</acronym>
- de los siguientes tipos: </para>
- <itemizedlist>
- <listitem>
- <para> MySQL, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/mysqli">mysqli</ulink>
- </para>
- </listitem>
- <listitem>
- <para> Oracle, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/oci8">oci8</ulink>
- </para>
- </listitem>
- <listitem>
- <para> IBM DB2, usando la extensión <acronym>PHP</acronym>
- <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
- </para>
- </listitem>
- <listitem>
- <para> Firebird/Interbase, usando la extensión
- <acronym>PHP</acronym>
- <ulink url="http://www.php.net/ibase"> php_interbase </ulink>
- </para>
- </listitem>
- </itemizedlist>
- <note>
- <para> Cada Zend_Db_Adaptador utiliza una extensión
- <acronym>PHP</acronym> . Se debe de tener habilitada la
- respectiva extensión en su entorno <acronym>PHP</acronym> para
- utilizar un <classname>Zend_Db_Adapter</classname> . Por ejemplo, si
- se utiliza una clase <classname>Zend_Db_Adapter</classname> basada
- en <acronym>PDO</acronym> , tiene que habilitar tanto la extensión
- <acronym>PDO</acronym> como el driver <acronym>PDO</acronym> del
- tipo de base de datos que se utiliza. </para>
- </note>
- <sect2 id="zend.db.adapter.connecting">
- <title> Conexión a una Base de Datos utilizando un Adaptador </title>
- <para> Esta sección describe cómo crear una instancia de un Adaptador de
- base de datos. Esto corresponde a establecer una conexión a un
- servidor de Base de Datos ( <acronym>RDBMS</acronym> ) desde su
- aplicación <acronym>PHP</acronym> . </para>
- <sect3 id="zend.db.adapter.connecting.constructor">
- <title>Usando un Constructor de Zend_Db Adapter</title>
- <para> Se puede crear una instancia de un Adaptador utilizando su
- constructor. Un constructor de adaptador toma un argumento, que
- es un conjunto de parámetros utilizados para declarar la
- conexión. </para>
- <example id="zend.db.adapter.connecting.constructor.example">
- <title>Usando el Constructor de un Adaptador</title>
- <programlisting language="php"><![CDATA[
- $db = new Zend_Db_Adapter_Pdo_Mysql(array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test'
- ));
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.factory">
- <title>Usando el Zend_Db Factory</title>
- <para> Como alternativa a la utilización directa del constructor de
- un adaptador, se puede crear una instancia del adaptador que use
- el método estático <methodname>Zend_Db::factory()</methodname> .
- Este método carga dinámicamente el archivo de clase Adaptador
- bajo demanda, usando <link linkend="zend.loader.load.class">
- Zend_Loader::loadClass() </link> . </para>
- <para> El primer argumento es una cadena que nombra al nombre base
- de la clase Adaptador. Por ejemplo, la cadena '
- <classname>Pdo_Mysql</classname> ' corresponde a la clase
- <classname>Zend_Db_Adapter_Pdo_Mysql</classname> . El
- segundo argumento es el mismo array de parámetros que hubiera
- enviado al constructor del adaptador. </para>
- <example id="zend.db.adapter.connecting.factory.example">
- <title>Usando el Adaptador del método factory</title>
- <programlisting language="php"><![CDATA[
- // No necesitamos la siguiente declaración, porque
- // el archivo Zend_Db_Adapter_Pdo_Mysql será cargado para nosotros por el método
- // factory de Zend_Db.
- // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
- // carga automaticamente la clase Zend_Db_Adapter_Pdo_Mysql
- // y crea una instancia de la misma
- $db = Zend_Db::factory('Pdo_Mysql', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test'
- ));
- ]]></programlisting>
- </example>
- <para> Si crea su propia clase que extiende a
- <classname>Zend_Db_Adapter_Abstract</classname> , pero no
- nombra su clase con el prefijo de paquete "
- <classname>Zend_Db_Adapter</classname> ", se puede utilizar
- el método <methodname>factory()</methodname> para cargar su
- adaptador si se especifica la parte principal de la clase del
- adaptador con la clave "adapterNamespace" en el conjunto de
- parámetros </para>
- <example id="zend.db.adapter.connecting.factory.example2">
- <title> Usando el método factory para una clase Adaptador
- personalizada </title>
- <programlisting language="php"><![CDATA[
- // No tenemos que cargar el archivo de clase Adaptador
- // porque será cargado para nosotros por el método factory de Zend_Db.
- // Automáticamente carga la clase MyProject_Db_Adapter_Pdo_Mysql
- // y crea una instancia de ella.
- $db = Zend_Db::factory('Pdo_Mysql', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'adapterNamespace' => 'MyProject_Db_Adapter'
- ));
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.factory-config">
- <title>Uso de Zend_Config con Zend_Db Factory</title>
- <para> Opcionalmente, se puede especificar cualquier argumento del
- método <methodname>factory()</methodname> como un objeto de tipo
- <link linkend="zend.config">Zend_Config</link> . </para>
- <para> Si el primer argumento es un objeto de configuración, se
- espera que contenga una propiedad llamada
- <property>adapter</property> , conteniendo la cadena que da
- nombre al nombre base de la clase de adaptador. Opcionalmente,
- el objeto puede contener una propiedad llamada
- <property>params</property> , con subpropiedades
- correspondientes a nombres de parámetros del adaptador. Esto es
- usado sólo si el segundo argumento del método
- <methodname>factory()</methodname> se ha omitido. </para>
- <example id="zend.db.adapter.connecting.factory.example1">
- <title> Uso del método factory del Adaptador con un objeto
- Zend_Config </title>
- <para> En el siguiente ejemplo, un objeto
- <classname>Zend_Config</classname> es creado usando un
- array. También puedes cargar los datos de un archivo
- externo, por ejemplo con <link
- linkend="zend.config.adapters.ini"> Zend_Config_Ini
- </link> o <link linkend="zend.config.adapters.xml">
- Zend_Config_Xml </link> . </para>
- <programlisting language="php"><![CDATA[
- $config = new Zend_Config(
- array(
- 'database' => array(
- 'adapter' => 'Mysqli',
- 'params' => array(
- 'dbname' => 'test',
- 'username' => 'webuser',
- 'password' => 'secret',
- )
- )
- )
- );
- $db = Zend_Db::factory($config->database);
- ]]></programlisting>
- </example>
- <para> El segundo argumento del método
- <methodname>factory()</methodname> puede ser un array
- asociativo con entradas correspondientes a los parámetros del
- adaptador. Este argumento es opcional. Si el primer argumento es
- de tipo <classname>Zend_Config</classname> , se asume que tiene
- todos los parametros, y el segundo argumento es ignorado. </para>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.parameters">
- <title>Parámetros del Adaptador</title>
- <para> El siguiente listado explica parámetros comunes reconocidos
- por Adaptador de clases <classname>Zend_Db</classname> . </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>host</emphasis> : una string conteniendo un
- nombre de host o dirección IP del servidor de base de
- datos. Si la base de datos está corriendo sobre el mismo
- host que la aplicación <acronym>PHP</acronym> , usted
- puede utilizar 'localhost' o '127.0.0.1'. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>username</emphasis> : identificador de cuenta
- para autenticar una conexión al servidor
- <acronym>RDBMS</acronym> . </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>password</emphasis> : la contraseña de la
- cuenta para la autenticación de credenciales de conexión
- con el servidor <acronym>RDBMS</acronym>
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>dbname</emphasis> : nombre de la base de datos
- en el servidor <acronym>RDBMS</acronym> . </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>port</emphasis> : algunos servidores
- <acronym>RDBMS</acronym> pueden aceptar conexiones
- de red sobre un número de puerto específico. El
- parámetro del puerto le permite especificar el puerto al
- que su aplicación <acronym>PHP</acronym> se conecta,
- para que concuerde el puerto configurado en el servidor
- <acronym>RDBMS</acronym> . </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>charset</emphasis> : specify the charset used
- for the connection. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>options</emphasis> : : este parámetro es un
- array asociativo de opciones que son genéricas a todas
- las clases <classname>Zend_Db_Adapter</classname> .
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis> driver_options </emphasis> : este parámetro
- es un array asociativo de opciones adicionales para una
- extensión de base de datos dada. un uso típico de este
- parámetro es establecer atributos de un driver
- <acronym>PDO</acronym> . </para>
- </listitem>
- <listitem>
- <para>
- <emphasis> adapterNamespace </emphasis> : nombre de la
- parte inicial del nombre de las clase para el adaptador,
- en lugar de ' <classname>Zend_Db_Adapter</classname> '.
- Utilice esto si usted necesita usar el método
- <methodname>factory()</methodname> para cargar un
- adaptador de clase de base de datos que no sea de Zend.
- </para>
- </listitem>
- </itemizedlist>
- <example id="zend.db.adapter.connecting.parameters.example1">
- <title> Passing the case-folding option to the factory </title>
- <para> Usted puede pasar esta opción específica por la constante
- <constant>Zend_Db::CASE_FOLDING</constant> . Este
- corresponde al atributo <constant>ATTR_CASE</constant> en
- los drivers de base de datos <acronym>PDO</acronym> e IBM
- DB2, ajustando la sensibilidad de las claves tipo cadena en
- los resultados de consultas. La opción toma los valores
- <constant>Zend_Db::CASE_NATURAL</constant> (el
- predeterminado), <constant>Zend_Db::CASE_UPPER</constant> ,
- y <constant>Zend_Db::CASE_LOWER</constant> . </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Db2', $params);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example2">
- <title> Passing the auto-quoting option to the factory </title>
- <para> Usted puede especificar esta opción por la constante
- <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> .
- Si el valor es <constant>TRUE</constant> (el
- predeterminado), los identificadores como nombres de tabla,
- nombres de columna, e incluso los alias son delimitados en
- la sintaxis <acronym>SQL</acronym> generada por el Adatador
- del objeto. Esto hace que sea sencillo utilizar
- identificadores que contengan palabras reservadas de
- <acronym>SQL</acronym> , o caracteres especiales. Si el
- valor es <constant>FALSE</constant> , los identificadores no
- son delimitados automáticamente. Si usted necesita delimitar
- identificadores, debe hacer usted mismo utilizando el método
- <methodname>quoteIdentifier()</methodname> . </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example3">
- <title>Passing PDO driver options to the factory</title>
- <programlisting language="php"><![CDATA[
- $pdoParams = array(
- PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'driver_options' => $pdoParams
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- echo $db->getConnection()
- ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example4">
- <title>Passing Serialization Options to the Factory</title>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::ALLOW_SERIALIZATION => false
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.getconnection">
- <title>Managing Lazy Connections</title>
- <para> Creating an instance of an Adapter class does not immediately
- connect to the <acronym>RDBMS</acronym> server. The Adapter
- saves the connection parameters, and makes the actual connection
- on demand, the first time you need to execute a query. This
- ensures that creating an Adapter object is quick and
- inexpensive. You can create an instance of an Adapter even if
- you are not certain that you need to run any database queries
- during the current request your application is serving. </para>
- <para> If you need to force the Adapter to connect to the
- <acronym>RDBMS</acronym> , use the
- <methodname>getConnection()</methodname> method. This method
- returns an object for the connection as represented by the
- respective <acronym>PHP</acronym> database extension. For
- example, if you use any of the Adapter classes for
- <acronym>PDO</acronym> drivers, then
- <methodname>getConnection()</methodname> returns the
- <acronym>PDO</acronym> object, after initiating it as a live
- connection to the specific database. </para>
- <para> It can be useful to force the connection if you want to catch
- any exceptions it throws as a result of invalid account
- credentials, or other failure to connect to the
- <acronym>RDBMS</acronym> server. These exceptions are not
- thrown until the connection is made, so it can help simplify
- your application code if you handle the exceptions in one place,
- instead of at the time of the first query against the database. </para>
- <para> Additionally, an adapter can get serialized to store it, for
- example, in a session variable. This can be very useful not only
- for the adapter itself, but for other objects that aggregate it,
- like a <classname>Zend_Db_Select</classname> object. By default,
- adapters are allowed to be serialized, if you don't want it, you
- should consider passing the
- <constant>Zend_Db::ALLOW_SERIALIZATION</constant> option
- with <constant>FALSE</constant> , see the example above. To
- respect lazy connections principle, the adapter won't reconnect
- itself after being unserialized. You must then call
- <methodname>getConnection()</methodname> yourself. You can
- make the adapter auto-reconnect by passing the
- <constant>Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE</constant>
- with <constant>TRUE</constant> as an adapter option. </para>
- <example id="zend.db.adapter.connecting.getconnection.example">
- <title>Handling connection exceptions</title>
- <programlisting language="php"><![CDATA[
- try {
- $db = Zend_Db::factory('Pdo_Mysql', $parameters);
- $db->getConnection();
- } catch (Zend_Db_Adapter_Exception $e) {
- // perhaps a failed login credential, or perhaps the RDBMS is not running
- } catch (Zend_Exception $e) {
- // perhaps factory() failed to load the specified Adapter class
- }
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.example-database">
- <title>La base de datos de ejemplo</title>
- <para> En la documentación de las clases <classname>Zend_Db</classname>
- , usamos un conjunto sencillo de tablas para ilustrar el uso de las
- clases y métodos. Estas tablas de ejemplo permiten almacenar
- información para localizar bugs en un proyecto de desarrollo de
- software. La base de datos contiene cuatro tablas: </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>accounts</emphasis> almacena información sobre
- cada usuario que hace el seguimiento de bugs. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>products</emphasis> almacena información sobre
- cada producto para el que pueden registrarse bugs. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>bugs</emphasis> almacena información sobre bugs,
- incluyendo el estado actual del bug, la persona que informó
- sobre el bug, la persona que está asignada para corregir el
- bug, y la persona que está asignada para verificar la
- corrección. </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>bugs_products</emphasis> stores a relationship
- between bugs and products. This implements a many-to-many
- relationship, because a given bug may be relevant to
- multiple products, and of course a given product can have
- multiple bugs. </para>
- </listitem>
- </itemizedlist>
- <para> La siguiente definición de datos <acronym>SQL</acronym> en
- lenguaje pseudocódigo describe las tablas de esta base de datos de
- ejemplo. Estas tablas de ejemplo son usadas ampliamente por los
- tests unitarios automatizados de <classname>Zend_Db</classname> . </para>
- <programlisting language="sql"><![CDATA[
- CREATE TABLE accounts (
- account_name VARCHAR(100) NOT NULL PRIMARY KEY
- );
- CREATE TABLE products (
- product_id INTEGER NOT NULL PRIMARY KEY,
- product_name VARCHAR(100)
- );
- CREATE TABLE bugs (
- bug_id INTEGER NOT NULL PRIMARY KEY,
- bug_description VARCHAR(100),
- bug_status VARCHAR(20),
- reported_by VARCHAR(100) REFERENCES accounts(account_name),
- assigned_to VARCHAR(100) REFERENCES accounts(account_name),
- verified_by VARCHAR(100) REFERENCES accounts(account_name)
- );
- CREATE TABLE bugs_products (
- bug_id INTEGER NOT NULL REFERENCES bugs,
- product_id INTEGER NOT NULL REFERENCES products,
- PRIMARY KEY (bug_id, product_id)
- );
- ]]></programlisting>
- <para> Also notice that the <code>bugs</code> table contains multiple
- foreign key references to the <code>accounts</code> table. Each of
- these foreign keys may reference a different row in the
- <code>accounts</code> table for a given bug. </para>
- <para> The diagram below illustrates the physical data model of the
- example database. </para>
- <para>
- <inlinegraphic width="387" scale="100" align="center"
- valign="middle"
- fileref="figures/zend.db.adapter.example-database.png"
- format="PNG"/>
- </para>
- </sect2>
- <sect2 id="zend.db.adapter.select">
- <title>Reading Query Results</title>
- <para> This section describes methods of the Adapter class with which
- you can run SELECT queries and retrieve the query results. </para>
- <sect3 id="zend.db.adapter.select.fetchall">
- <title>Fetching a Complete Result Set</title>
- <para> You can run a <acronym>SQL</acronym> SELECT query and
- retrieve its results in one step using the
- <methodname>fetchAll()</methodname> method. </para>
- <para> The first argument to this method is a string containing a
- SELECT statement. Alternatively, the first argument can be an
- object of class <link linkend="zend.db.select"
- >Zend_Db_Select</link> . The Adapter automatically converts
- this object to a string representation of the SELECT statement. </para>
- <para> The second argument to <methodname>fetchAll()</methodname> is
- an array of values to substitute for parameter placeholders in
- the <acronym>SQL</acronym> statement. </para>
- <example id="zend.db.adapter.select.fetchall.example">
- <title>Using fetchAll()</title>
- <programlisting language="php"><![CDATA[
- $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
- $result = $db->fetchAll($sql, 2);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetch-mode">
- <title>Changing the Fetch Mode</title>
- <para> By default, <methodname>fetchAll()</methodname> returns an
- array of rows, each of which is an associative array. The keys
- of the associative array are the columns or column aliases named
- in the select query. </para>
- <para> You can specify a different style of fetching results using
- the <methodname>setFetchMode()</methodname> method. The modes
- supported are identified by constants: </para>
- <itemizedlist>
- <listitem>
- <para>
- <constant>Zend_Db::FETCH_ASSOC</constant> : return data
- in an array of associative arrays. The array keys are
- column names, as strings. This is the default fetch mode
- for <classname>Zend_Db_Adapter</classname> classes. </para>
- <para> Note that if your select-list contains more than one
- column with the same name, for example if they are from
- two different tables in a JOIN, there can be only one
- entry in the associative array for a given name. If you
- use the FETCH_ASSOC mode, you should specify column
- aliases in your SELECT query to ensure that the names
- result in unique array keys. </para>
- <para> By default, these strings are returned as they are
- returned by the database driver. This is typically the
- spelling of the column in the <acronym>RDBMS</acronym>
- server. You can specify the case for these strings,
- using the <constant>Zend_Db::CASE_FOLDING</constant>
- option. Specify this when instantiating the Adapter. See
- <xref
- linkend="zend.db.adapter.connecting.parameters.example1"
- /> . </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db::FETCH_NUM</constant> : return data in
- an array of arrays. The arrays are indexed by integers,
- corresponding to the position of the respective field in
- the select-list of the query. </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db::FETCH_BOTH</constant> : return data
- in an array of arrays. The array keys are both strings
- as used in the FETCH_ASSOC mode, and integers as used in
- the FETCH_NUM mode. Note that the number of elements in
- the array is double that which would be in the array if
- you used either FETCH_ASSOC or FETCH_NUM. </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db::FETCH_COLUMN</constant> : return data
- in an array of values. The value in each array is the
- value returned by one column of the result set. By
- default, this is the first column, indexed by 0. </para>
- </listitem>
- <listitem>
- <para>
- <constant>Zend_Db::FETCH_OBJ</constant> : return data in
- an array of objects. The default class is the
- <acronym>PHP</acronym> built-in class stdClass.
- Columns of the result set are available as public
- properties of the object. </para>
- </listitem>
- </itemizedlist>
- <example id="zend.db.adapter.select.fetch-mode.example">
- <title>Using setFetchMode()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
- // $result is an array of objects
- echo $result[0]->bug_description;
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchassoc">
- <title>Fetching a Result Set as an Associative Array</title>
- <para> The <methodname>fetchAssoc()</methodname> method returns data
- in an array of associative arrays, regardless of what value you
- have set for the fetch mode. </para>
- <example id="zend.db.adapter.select.fetchassoc.example">
- <title>Using fetchAssoc()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
- // $result is an array of associative arrays, in spite of the fetch mode
- echo $result[0]['bug_description'];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchcol">
- <title>Fetching a Single Column from a Result Set</title>
- <para> The <methodname>fetchCol()</methodname> method returns data
- in an array of values, regardless of the value you have set for
- the fetch mode. This only returns the first column returned by
- the query. Any other columns returned by the query are
- discarded. If you need to return a column other than the first,
- see <xref linkend="zend.db.statement.fetching.fetchcolumn"/> . </para>
- <example id="zend.db.adapter.select.fetchcol.example">
- <title>Using fetchCol()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchCol(
- 'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
- // contains bug_description; bug_id is not returned
- echo $result[0];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchpairs">
- <title>Fetching Key-Value Pairs from a Result Set</title>
- <para> The <methodname>fetchPairs()</methodname> method returns data
- in an array of key-value pairs, as an associative array with a
- single entry per row. The key of this associative array is taken
- from the first column returned by the SELECT query. The value is
- taken from the second column returned by the SELECT query. Any
- other columns returned by the query are discarded. </para>
- <para> You should design the SELECT query so that the first column
- returned has unique values. If there are duplicates values in
- the first column, entries in the associative array will be
- overwritten. </para>
- <example id="zend.db.adapter.select.fetchpairs.example">
- <title>Using fetchPairs()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
- echo $result[2];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchrow">
- <title>Fetching a Single Row from a Result Set</title>
- <para> The <methodname>fetchRow()</methodname> method returns data
- using the current fetch mode, but it returns only the first row
- fetched from the result set. </para>
- <example id="zend.db.adapter.select.fetchrow.example">
- <title>Using fetchRow()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
- // note that $result is a single object, not an array of objects
- echo $result->bug_description;
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchone">
- <title>Fetching a Single Scalar from a Result Set</title>
- <para> The <methodname>fetchOne()</methodname> method is like a
- combination of <methodname>fetchRow()</methodname> with
- <methodname>fetchCol()</methodname> , in that it returns
- data only for the first row fetched from the result set, and it
- returns only the value of the first column in that row.
- Therefore it returns only a single scalar value, not an array or
- an object. </para>
- <example id="zend.db.adapter.select.fetchone.example">
- <title>Using fetchOne()</title>
- <programlisting language="php"><![CDATA[
- $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
- // this is a single string value
- echo $result;
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.write">
- <title>Writing Changes to the Database</title>
- <para> You can use the Adapter class to write new data or change
- existing data in your database. This section describes methods to do
- these operations. </para>
- <sect3 id="zend.db.adapter.write.insert">
- <title>Inserting Data</title>
- <para> You can add new rows to a table in your database using the
- <methodname>insert()</methodname> method. The first argument
- is a string that names the table, and the second argument is an
- associative array, mapping column names to data values. </para>
- <example id="zend.db.adapter.write.insert.example">
- <title>Inserting in a Table</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'created_on' => '2007-03-22',
- 'bug_description' => 'Something wrong',
- 'bug_status' => 'NEW'
- );
- $db->insert('bugs', $data);
- ]]></programlisting>
- </example>
- <para> Columns you exclude from the array of data are not specified
- to the database. Therefore, they follow the same rules that an
- <acronym>SQL</acronym> INSERT statement follows: if the
- column has a DEFAULT clause, the column takes that value in the
- row created, otherwise the column is left in a <acronym>NULL</acronym> state. </para>
- <para> By default, the values in your data array are inserted using
- parameters. This reduces risk of some types of security issues.
- You don't need to apply escaping or quoting to values in the
- data array. </para>
- <para> You might need values in the data array to be treated as
- <acronym>SQL</acronym> expressions, in which case they
- should not be quoted. By default, all data values passed as
- strings are treated as string literals. To specify that the
- value is an <acronym>SQL</acronym> expression and therefore
- should not be quoted, pass the value in the data array as an
- object of type <classname>Zend_Db_Expr</classname> instead of a
- plain string. </para>
- <example id="zend.db.adapter.write.insert.example2">
- <title>Inserting Expressions in a Table</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'created_on' => new Zend_Db_Expr('CURDATE()'),
- 'bug_description' => 'Something wrong',
- 'bug_status' => 'NEW'
- );
- $db->insert('bugs', $data);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.write.lastinsertid">
- <title>Retrieving a Generated Value</title>
- <para> Some <acronym>RDBMS</acronym> brands support
- auto-incrementing primary keys. A table defined this way
- generates a primary key value automatically during an INSERT of
- a new row. The return value of the
- <methodname>insert()</methodname> method is
- <emphasis>not</emphasis> the last inserted ID, because the
- table might not have an auto-incremented column. Instead, the
- return value is the number of rows affected (usually 1). </para>
- <para> If your table is defined with an auto-incrementing primary
- key, you can call the <methodname>lastInsertId()</methodname>
- method after the insert. This method returns the last value
- generated in the scope of the current database connection. </para>
- <example id="zend.db.adapter.write.lastinsertid.example-1">
- <title>Using lastInsertId() for an Auto-Increment Key</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // return the last value generated by an auto-increment column
- $id = $db->lastInsertId();
- ]]></programlisting>
- </example>
- <para> Some <acronym>RDBMS</acronym> brands support a sequence
- object, which generates unique values to serve as primary key
- values. To support sequences, the
- <methodname>lastInsertId()</methodname> method accepts two
- optional string arguments. These arguments name the table and
- the column, assuming you have followed the convention that a
- sequence is named using the table and column names for which the
- sequence generates values, and a suffix "_seq". This is based on
- the convention used by PostgreSQL when naming sequences for
- SERIAL columns. For example, a table "bugs" with primary key
- column "bug_id" would use a sequence named "bugs_bug_id_seq". </para>
- <example id="zend.db.adapter.write.lastinsertid.example-2">
- <title>Using lastInsertId() for a Sequence</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // return the last value generated by sequence 'bugs_bug_id_seq'.
- $id = $db->lastInsertId('bugs', 'bug_id');
- // alternatively, return the last value generated by sequence 'bugs_seq'.
- $id = $db->lastInsertId('bugs');
- ]]></programlisting>
- </example>
- <para> If the name of your sequence object does not follow this
- naming convention, use the
- <methodname>lastSequenceId()</methodname> method instead.
- This method takes a single string argument, naming the sequence
- literally. </para>
- <example id="zend.db.adapter.write.lastinsertid.example-3">
- <title>Using lastSequenceId()</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // return the last value generated by sequence 'bugs_id_gen'.
- $id = $db->lastSequenceId('bugs_id_gen');
- ]]></programlisting>
- </example>
- <para> For <acronym>RDBMS</acronym> brands that don't support
- sequences, including MySQL, Microsoft <acronym>SQL</acronym>
- Server, and SQLite, the arguments to the lastInsertId() method
- are ignored, and the value returned is the most recent value
- generated for any table by INSERT operations during the current
- connection. For these <acronym>RDBMS</acronym> brands, the
- lastSequenceId() method always returns <constant>NULL</constant>
- . </para>
- <note>
- <title>Why Not Use "SELECT MAX(id) FROM table"?</title>
- <para> Sometimes this query returns the most recent primary key
- value inserted into the table. However, this technique is
- not safe to use in an environment where multiple clients are
- inserting records to the database. It is possible, and
- therefore is bound to happen eventually, that another client
- inserts another row in the instant between the insert
- performed by your client application and your query for the
- MAX(id) value. Thus the value returned does not identify the
- row you inserted, it identifies the row inserted by some
- other client. There is no way to know when this has
- happened. </para>
- <para> Using a strong transaction isolation mode such as
- "repeatable read" can mitigate this risk, but some
- <acronym>RDBMS</acronym> brands don't support the
- transaction isolation required for this, or else your
- application may use a lower transaction isolation mode by
- design. </para>
- <para> Furthermore, using an expression like "MAX(id)+1" to
- generate a new value for a primary key is not safe, because
- two clients could do this query simultaneously, and then
- both use the same calculated value for their next INSERT
- operation. </para>
- <para> All <acronym>RDBMS</acronym> brands provide mechanisms to
- generate unique values, and to return the last value
- generated. These mechanisms necessarily work outside of the
- scope of transaction isolation, so there is no chance of two
- clients generating the same value, and there is no chance
- that the value generated by another client could be reported
- to your client's connection as the last value generated.
- </para>
- </note>
- </sect3>
- <sect3 id="zend.db.adapter.write.update">
- <title>Updating Data</title>
- <para> You can update rows in a database table using the
- <methodname>update()</methodname> method of an Adapter. This
- method takes three arguments: the first is the name of the
- table; the second is an associative array mapping columns to
- change to new values to assign to these columns. </para>
- <para> The values in the data array are treated as string literals.
- See <xref linkend="zend.db.adapter.write.insert"/> for
- information on using <acronym>SQL</acronym> expressions in the
- data array. </para>
- <para> The third argument is a string containing an
- <acronym>SQL</acronym> expression that is used as criteria
- for the rows to change. The values and identifiers in this
- argument are not quoted or escaped. You are responsible for
- ensuring that any dynamic content is interpolated into this
- string safely. See <xref linkend="zend.db.adapter.quoting"/> for
- methods to help you do this. </para>
- <para> The return value is the number of rows affected by the update
- operation. </para>
- <example id="zend.db.adapter.write.update.example">
- <title>Updating Rows</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $n = $db->update('bugs', $data, 'bug_id = 2');
- ]]></programlisting>
- </example>
- <para> If you omit the third argument, then all rows in the database
- table are updated with the values specified in the data array. </para>
- <para> If you provide an array of strings as the third argument,
- these strings are joined together as terms in an expression
- separated by <constant>AND</constant> operators. </para>
- <example id="zend.db.adapter.write.update.example-array">
- <title>Updating Rows Using an Array of Expressions</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $where[] = "reported_by = 'goofy'";
- $where[] = "bug_status = 'OPEN'";
- $n = $db->update('bugs', $data, $where);
- // Resulting SQL is:
- // UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
- // WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.write.delete">
- <title>Deleting Data</title>
- <para> You can delete rows from a database table using the
- <methodname>delete()</methodname> method. This method takes
- two arguments: the first is a string naming the table. </para>
- <para> The second argument is a string containing an
- <acronym>SQL</acronym> expression that is used as criteria
- for the rows to delete. The values and identifiers in this
- argument are not quoted or escaped. You are responsible for
- ensuring that any dynamic content is interpolated into this
- string safely. See <xref linkend="zend.db.adapter.quoting"/> for
- methods to help you do this. </para>
- <para> The return value is the number of rows affected by the delete
- operation. </para>
- <example id="zend.db.adapter.write.delete.example">
- <title>Deleting Rows</title>
- <programlisting language="php"><![CDATA[
- $n = $db->delete('bugs', 'bug_id = 3');
- ]]></programlisting>
- </example>
- <para> If you omit the second argument, the result is that all rows
- in the database table are deleted. </para>
- <para> If you provide an array of strings as the second argument,
- these strings are joined together as terms in an expression
- separated by <constant>AND</constant> operators. </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.quoting">
- <title>Quoting Values and Identifiers</title>
- <para> When you form <acronym>SQL</acronym> queries, often it is the
- case that you need to include the values of PHP variables in
- <acronym>SQL</acronym> expressions. This is risky, because if
- the value in a PHP string contains certain symbols, such as the
- quote symbol, it could result in invalid <acronym>SQL</acronym> .
- For example, notice the imbalanced quote characters in the following
- query: <programlisting language="php"><![CDATA[
- $name = "O'Reilly";
- $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
- ]]></programlisting>
- </para>
- <para> Even worse is the risk that such code mistakes might be exploited
- deliberately by a person who is trying to manipulate the function of
- your web application. If they can specify the value of a
- <acronym>PHP</acronym> variable through the use of an
- <acronym>HTTP</acronym> parameter or other mechanism, they might
- be able to make your <acronym>SQL</acronym> queries do things that
- you didn't intend them to do, such as return data to which the
- person should not have privilege to read. This is a serious and
- widespread technique for violating application security, known as
- "SQL Injection" (see <ulink
- url="http://en.wikipedia.org/wiki/SQL_Injection"
- >http://en.wikipedia.org/wiki/SQL_Injection</ulink> ). </para>
- <para> The <classname>Zend_Db</classname> Adapter class provides
- convenient functions to help you reduce vulnerabilities to
- <acronym>SQL</acronym> Injection attacks in your
- <acronym>PHP</acronym> code. The solution is to escape special
- characters such as quotes in <acronym>PHP</acronym> values before
- they are interpolated into your <acronym>SQL</acronym> strings. This
- protects against both accidental and deliberate manipulation of
- <acronym>SQL</acronym> strings by <acronym>PHP</acronym>
- variables that contain special characters. </para>
- <sect3 id="zend.db.adapter.quoting.quote">
- <title>Using quote()</title>
- <para> The <methodname>quote()</methodname> method accepts a single
- argument, a scalar string value. It returns the value with
- special characters escaped in a manner appropriate for the
- <acronym>RDBMS</acronym> you are using, and surrounded by
- string value delimiters. The standard <acronym>SQL</acronym>
- string value delimiter is the single-quote ( <code>'</code> ). </para>
- <example id="zend.db.adapter.quoting.quote.example">
- <title>Using quote()</title>
- <programlisting language="php"><![CDATA[
- $name = $db->quote("O'Reilly");
- echo $name;
- // 'O\'Reilly'
- $sql = "SELECT * FROM bugs WHERE reported_by = $name";
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
- ]]></programlisting>
- </example>
- <para> Note that the return value of
- <methodname>quote()</methodname> includes the quote
- delimiters around the string. This is different from some
- functions that escape special characters but do not add the
- quote delimiters, for example <ulink
- url="http://www.php.net/mysqli_real_escape_string"
- >mysql_real_escape_string()</ulink> . </para>
- <para> Values may need to be quoted or not quoted according to the
- <acronym>SQL</acronym> datatype context in which they are
- used. For instance, in some RDBMS brands, an integer value must
- not be quoted as a string if it is compared to an integer-type
- column or expression. In other words, the following is an error
- in some <acronym>SQL</acronym> implementations, assuming
- <code>intColumn</code> has a <acronym>SQL</acronym> datatype
- of <constant>INTEGER</constant>
- <programlisting language="php"><![CDATA[
- SELECT * FROM atable WHERE intColumn = '123'
- ]]></programlisting>
- </para>
- <para> You can use the optional second argument to the
- <methodname>quote()</methodname> method to apply quoting
- selectively for the <acronym>SQL</acronym> datatype you specify. </para>
- <example id="zend.db.adapter.quoting.quote.example-2">
- <title>Using quote() with a SQL Type</title>
- <programlisting language="php"><![CDATA[
- $value = '1234';
- $sql = 'SELECT * FROM atable WHERE intColumn = '
- . $db->quote($value, 'INTEGER');
- ]]></programlisting>
- </example>
- <para> Each <classname>Zend_Db_Adapter</classname> class has encoded
- the names of numeric <acronym>SQL</acronym> datatypes for the
- respective brand of <acronym>RDBMS</acronym> . You can also use
- the constants <constant>Zend_Db::INT_TYPE</constant> ,
- <constant>Zend_Db::BIGINT_TYPE</constant> , and
- <constant>Zend_Db::FLOAT_TYPE</constant> to write code in a
- more <acronym>RDBMS</acronym> -independent way. </para>
- <para>
- <classname>Zend_Db_Table</classname> specifies
- <acronym>SQL</acronym> types to
- <methodname>quote()</methodname> automatically when
- generating <acronym>SQL</acronym> queries that reference a
- table's key columns. </para>
- </sect3>
- <sect3 id="zend.db.adapter.quoting.quote-into">
- <title>Using quoteInto()</title>
- <para> The most typical usage of quoting is to interpolate a
- <acronym>PHP</acronym> variable into a
- <acronym>SQL</acronym> expression or statement. You can use
- the <methodname>quoteInto()</methodname> method to do this in
- one step. This method takes two arguments: the first argument is
- a string containing a placeholder symbol ( <code>?</code> ), and
- the second argument is a value or <acronym>PHP</acronym>
- variable that should be substituted for that placeholder. </para>
- <para> The placeholder symbol is the same symbol used by many
- <acronym>RDBMS</acronym> brands for positional parameters,
- but the <methodname>quoteInto()</methodname> method only
- emulates query parameters. The method simply interpolates the
- value into the string, escapes special characters, and applies
- quotes around it. True query parameters maintain the separation
- between the <acronym>SQL</acronym> string and the parameters as
- the statement is parsed in the <acronym>RDBMS</acronym> server. </para>
- <example id="zend.db.adapter.quoting.quote-into.example">
- <title>Using quoteInto()</title>
- <programlisting language="php"><![CDATA[
- $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
- ]]></programlisting>
- </example>
- <para> You can use the optional third parameter of
- <methodname>quoteInto()</methodname> to specify the
- <acronym>SQL</acronym> datatype. Numeric datatypes are not
- quoted, and other types are quoted. </para>
- <example id="zend.db.adapter.quoting.quote-into.example-2">
- <title>Using quoteInto() with a SQL Type</title>
- <programlisting language="php"><![CDATA[
- $sql = $db
- ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 1234
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.quoting.quote-identifier">
- <title>Using quoteIdentifier()</title>
- <para> Values are not the only part of <acronym>SQL</acronym> syntax
- that might need to be variable. If you use
- <acronym>PHP</acronym> variables to name tables, columns, or
- other identifiers in your <acronym>SQL</acronym> statements, you
- might need to quote these strings too. By default,
- <acronym>SQL</acronym> identifiers have syntax rules like
- <acronym>PHP</acronym> and most other programming languages.
- For example, identifiers should not contain spaces, certain
- punctuation or special characters, or international characters.
- Also certain words are reserved for <acronym>SQL</acronym>
- syntax, and should not be used as identifiers. </para>
- <para> However, <acronym>SQL</acronym> has a feature called
- <emphasis>delimited identifiers</emphasis> , which allows
- broader choices for the spelling of identifiers. If you enclose
- a <acronym>SQL</acronym> identifier in the proper types of
- quotes, you can use identifiers with spellings that would be
- invalid without the quotes. Delimited identifiers can contain
- spaces, punctuation, or international characters. You can also
- use <acronym>SQL</acronym> reserved words if you enclose them in
- identifier delimiters. </para>
- <para> The <methodname>quoteIdentifier()</methodname> method works
- like <methodname>quote()</methodname> , but it applies the
- identifier delimiter characters to the string according to the
- type of Adapter you use. For example, standard
- <acronym>SQL</acronym> uses double-quotes ( <code>"</code> )
- for identifier delimiters, and most <acronym>RDBMS</acronym>
- brands use that symbol. MySQL uses back-quotes ( <code>`</code>
- ) by default. The <methodname>quoteIdentifier()</methodname>
- method also escapes special characters within the string
- argument. </para>
- <example id="zend.db.adapter.quoting.quote-identifier.example">
- <title>Using quoteIdentifier()</title>
- <programlisting language="php"><![CDATA[
- // we might have a table name that is an SQL reserved word
- $tableName = $db->quoteIdentifier("order");
- $sql = "SELECT * FROM $tableName";
- echo $sql
- // SELECT * FROM "order"
- ]]></programlisting>
- </example>
- <para>
- <acronym>SQL</acronym> delimited identifiers are case-sensitive,
- unlike unquoted identifiers. Therefore, if you use delimited
- identifiers, you must use the spelling of the identifier exactly
- as it is stored in your schema, including the case of the
- letters. </para>
- <para> In most cases where <acronym>SQL</acronym> is generated
- within <classname>Zend_Db</classname> classes, the default is
- that all identifiers are delimited automatically. You can change
- this behavior with the option
- <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> .
- Specify this when instantiating the Adapter. See <xref
- linkend="zend.db.adapter.connecting.parameters.example2"/> . </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.transactions">
- <title>Controlling Database Transactions</title>
- <para> Databases define transactions as logical units of work that can
- be committed or rolled back as a single change, even if they operate
- on multiple tables. All queries to a database are executed within
- the context of a transaction, even if the database driver manages
- them implicitly. This is called <emphasis>auto-commit</emphasis>
- mode, in which the database driver creates a transaction for every
- statement you execute, and commits that transaction after your
- <acronym>SQL</acronym> statement has been executed. By default,
- all <classname>Zend_Db</classname> Adapter classes operate in
- auto-commit mode. </para>
- <para> Alternatively, you can specify the beginning and resolution of a
- transaction, and thus control how many <acronym>SQL</acronym>
- queries are included in a single group that is committed (or rolled
- back) as a single operation. Use the
- <methodname>beginTransaction()</methodname> method to initiate a
- transaction. Subsequent <acronym>SQL</acronym> statements are
- executed in the context of the same transaction until you resolve it
- explicitly. </para>
- <para> To resolve the transaction, use either the
- <methodname>commit()</methodname> or
- <methodname>rollBack()</methodname> methods. The
- <methodname>commit()</methodname> method marks changes made
- during your transaction as committed, which means the effects of
- these changes are shown in queries run in other transactions. </para>
- <para> The <methodname>rollBack()</methodname> method does the opposite:
- it discards the changes made during your transaction. The changes
- are effectively undone, and the state of the data returns to how it
- was before you began your transaction. However, rolling back your
- transaction has no effect on changes made by other transactions
- running concurrently. </para>
- <para> After you resolve this transaction,
- <classname>Zend_Db_Adapter</classname> returns to auto-commit
- mode until you call <methodname>beginTransaction()</methodname>
- again. </para>
- <example id="zend.db.adapter.transactions.example">
- <title>Managing a Transaction to Ensure Consistency</title>
- <programlisting language="php"><![CDATA[
- // Start a transaction explicitly.
- $db->beginTransaction();
- try {
- // Attempt to execute one or more queries:
- $db->query(...);
- $db->query(...);
- $db->query(...);
- // If all succeed, commit the transaction and all changes
- // are committed at once.
- $db->commit();
- } catch (Exception $e) {
- // If any of the queries failed and threw an exception,
- // we want to roll back the whole transaction, reversing
- // changes made in the transaction, even those that succeeded.
- // Thus all changes are committed together, or none are.
- $db->rollBack();
- echo $e->getMessage();
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.adapter.list-describe">
- <title>Listing and Describing Tables</title>
- <para> The <methodname>listTables()</methodname> method returns an array
- of strings, naming all tables in the current database. </para>
- <para> The <methodname>describeTable()</methodname> method returns an
- associative array of metadata about a table. Specify the name of the
- table as a string in the first argument to this method. The second
- argument is optional, and names the schema in which the table
- exists. </para>
- <para> The keys of the associative array returned are the column names
- of the table. The value corresponding to each column is also an
- associative array, with the following keys and values: </para>
- <table frame="all" cellpadding="5"
- id="zend.db.adapter.list-describe.metadata">
- <title>Metadata Fields Returned by describeTable()</title>
- <tgroup cols="3" align="left" colsep="1" rowsep="1">
- <thead>
- <row>
- <entry>Key</entry>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <constant>SCHEMA_NAME</constant>
- </entry>
- <entry>(string)</entry>
- <entry>Name of the database schema in which this table
- exists.</entry>
- </row>
- <row>
- <entry>
- <constant>TABLE_NAME</constant>
- </entry>
- <entry>(string)</entry>
- <entry>Name of the table to which this column
- belongs.</entry>
- </row>
- <row>
- <entry>
- <constant>COLUMN_NAME</constant>
- </entry>
- <entry>(string)</entry>
- <entry>Name of the column.</entry>
- </row>
- <row>
- <entry>
- <constant>COLUMN_POSITION</constant>
- </entry>
- <entry>(integer)</entry>
- <entry>Ordinal position of the column in the
- table.</entry>
- </row>
- <row>
- <entry>
- <constant>DATA_TYPE</constant>
- </entry>
- <entry>(string)</entry>
- <entry>RDBMS name of the datatype of the column.</entry>
- </row>
- <row>
- <entry>
- <constant>DEFAULT</constant>
- </entry>
- <entry>(string)</entry>
- <entry>Default value for the column, if any.</entry>
- </row>
- <row>
- <entry>
- <constant>NULLABLE</constant>
- </entry>
- <entry>(boolean)</entry>
- <entry> <constant>TRUE</constant> if the column accepts
- <acronym>SQL</acronym> <constant>NULL</constant>s, <constant>FALSE</constant> if the
- column has a <constant>NOT</constant> <constant>NULL</constant> constraint. </entry>
- </row>
- <row>
- <entry>
- <constant>LENGTH</constant>
- </entry>
- <entry>(integer)</entry>
- <entry> Length or size of the column as reported by the
- <acronym>RDBMS</acronym> . </entry>
- </row>
- <row>
- <entry>
- <constant>SCALE</constant>
- </entry>
- <entry>(integer)</entry>
- <entry> Scale of <acronym>SQL</acronym> NUMERIC or
- <constant>DECIMAL</constant> type. </entry>
- </row>
- <row>
- <entry>
- <constant>PRECISION</constant>
- </entry>
- <entry>(integer)</entry>
- <entry> Precision of <acronym>SQL</acronym> NUMERIC or
- <constant>DECIMAL</constant> type. </entry>
- </row>
- <row>
- <entry>
- <constant>UNSIGNED</constant>
- </entry>
- <entry>(boolean)</entry>
- <entry> <constant>TRUE</constant> if an integer-based type is reported as
- <constant>UNSIGNED</constant> . </entry>
- </row>
- <row>
- <entry>
- <constant>PRIMARY</constant>
- </entry>
- <entry>(boolean)</entry>
- <entry><constant>TRUE</constant> if the column is part of the primary key of
- this table.</entry>
- </row>
- <row>
- <entry>
- <constant>PRIMARY_POSITION</constant>
- </entry>
- <entry>(integer)</entry>
- <entry>Ordinal position (1-based) of the column in the
- primary key.</entry>
- </row>
- <row>
- <entry>
- <constant>IDENTITY</constant>
- </entry>
- <entry>(boolean)</entry>
- <entry><constant>TRUE</constant> if the column uses an auto-generated
- value.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <note>
- <title>How the IDENTITY Metadata Field Relates to Specific
- RDBMSs</title>
- <para> The IDENTITY metadata field was chosen as an 'idiomatic' term
- to represent a relation to surrogate keys. This field can be
- commonly known by the following values:- </para>
- <itemizedlist>
- <listitem>
- <para>
- <constant>IDENTITY</constant> - DB2, MSSQL </para>
- </listitem>
- <listitem>
- <para>
- <constant>AUTO_INCREMENT</constant> - MySQL </para>
- </listitem>
- <listitem>
- <para>
- <constant>SERIAL</constant> - PostgreSQL </para>
- </listitem>
- <listitem>
- <para>
- <constant>SEQUENCE</constant> - Oracle </para>
- </listitem>
- </itemizedlist>
- </note>
- <para> If no table exists matching the table name and optional schema
- name specified, then <methodname>describeTable()</methodname>
- returns an empty array. </para>
- </sect2>
- <sect2 id="zend.db.adapter.closing">
- <title>Closing a Connection</title>
- <para> Normally it is not necessary to close a database connection.
- <acronym>PHP</acronym> automatically cleans up all resources and
- the end of a request. Database extensions are designed to close the
- connection as the reference to the resource object is cleaned up. </para>
- <para> However, if you have a long-duration <acronym>PHP</acronym>
- script that initiates many database connections, you might need to
- close the connection, to avoid exhausting the capacity of your
- <acronym>RDBMS</acronym> server. You can use the Adapter's
- <methodname>closeConnection()</methodname> method to explicitly
- close the underlying database connection. </para>
- <para> Since release 1.7.2, you could check you are currently connected
- to the <acronym>RDBMS</acronym> server with the method
- <methodname>isConnected()</methodname> . This means that a
- connection resource has been initiated and wasn't closed. This
- function is not currently able to test for example a server side
- closing of the connection. This is internally use to close the
- connection. It allow you to close the connection multiple times
- without errors. It was already the case before 1.7.2 for
- <acronym>PDO</acronym> adapters but not for the others. </para>
- <example id="zend.db.adapter.closing.example">
- <title>Closing a Database Connection</title>
- <programlisting language="php"><![CDATA[
- $db->closeConnection();
- ]]></programlisting>
- </example>
- <note>
- <title>Does Zend_Db Support Persistent Connections?</title>
- <para> Yes, persistence is supported through the addition of the
- <property>persistent</property> flag set to true in the
- configuration (not driver_configuration) of an adapter in
- <classname>Zend_Db</classname> . </para>
- <example id="zend.db.adapter.connecting.persistence.example">
- <title>Using the Persitence Flag with the Oracle Adapter</title>
- <programlisting language="php"><![CDATA[
- $db = Zend_Db::factory('Oracle', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'persistent' => true
- ));
- ]]></programlisting>
- </example>
- <para> Please note that using persistent connections can cause an
- excess of idle connections on the <acronym>RDBMS</acronym>
- server, which causes more problems than any performance gain you
- might achieve by reducing the overhead of making connections. </para>
- <para> Database connections have state. That is, some objects in the
- <acronym>RDBMS</acronym> server exist in session scope.
- Examples are locks, user variables, temporary tables, and
- information about the most recently executed query, such as rows
- affected, and last generated id value. If you use persistent
- connections, your application could access invalid or privileged
- data that were created in a previous <acronym>PHP</acronym>
- request. </para>
- <para> Currently, only Oracle, DB2, and the <acronym>PDO</acronym>
- adapters (where specified by <acronym>PHP</acronym> ) support
- persistence in <classname>Zend_Db</classname> . </para>
- </note>
- </sect2>
- <sect2 id="zend.db.adapter.other-statements">
- <title>Running Other Database Statements</title>
- <para> There might be cases in which you need to access the connection
- object directly, as provided by the <acronym>PHP</acronym> database
- extension. Some of these extensions may offer features that are not
- surfaced by methods of
- <classname>Zend_Db_Adapter_Abstract</classname> . </para>
- <para> For example, all <acronym>SQL</acronym> statements run by
- <classname>Zend_Db</classname> are prepared, then executed.
- However, some database features are incompatible with prepared
- statements. DDL statements like CREATE and ALTER cannot be prepared
- in MySQL. Also, <acronym>SQL</acronym> statements don't benefit from
- the <ulink
- url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html"
- >MySQL Query Cache</ulink> , prior to MySQL 5.1.17. </para>
- <para> Most <acronym>PHP</acronym> database extensions provide a method
- to execute <acronym>SQL</acronym> statements without preparing them.
- For example, in <acronym>PDO</acronym> , this method is
- <methodname>exec()</methodname> . You can access the connection
- object in the <acronym>PHP</acronym> extension directly using
- getConnection(). </para>
- <example id="zend.db.adapter.other-statements.example">
- <title>Running a Non-Prepared Statement in a PDO Adapter</title>
- <programlisting language="php"><![CDATA[
- $result = $db->getConnection()->exec('DROP TABLE bugs');
- ]]></programlisting>
- </example>
- <para> Similarly, you can access other methods or properties that are
- specific to <acronym>PHP</acronym> database extensions. Be aware,
- though, that by doing this you might constrain your application to
- the interface provided by the extension for a specific brand of
- <acronym>RDBMS</acronym> . </para>
- <para> In future versions of <classname>Zend_Db</classname> , there will
- be opportunities to add method entry points for functionality that
- is common to the supported <acronym>PHP</acronym> database
- extensions. This will not affect backward compatibility. </para>
- </sect2>
- <sect2 id="zend.db.adapter.server-version">
- <title>Retrieving Server Version</title>
- <para> Since release 1.7.2, you could retrieve the server version in
- <acronym>PHP</acronym> syntax style to be able to use
- <methodname>version_compare()</methodname> . If the information
- isn't available, you will receive <constant>NULL</constant> . </para>
- <example id="zend.db.adapter.server-version.example">
- <title>Verifying server version before running a query</title>
- <programlisting language="php"><![CDATA[
- $version = $db->getServerVersion();
- if (!is_null($version)) {
- if (version_compare($version, '5.0.0', '>=')) {
- // do something
- } else {
- // do something else
- }
- } else {
- // impossible to read server version
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.adapter.adapter-notes">
- <title>Notes on Specific Adapters</title>
- <para> This section lists differences between the Adapter classes of
- which you should be aware. </para>
- <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
- <title>IBM DB2</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the factory() method with the
- name 'Db2'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extension ibm_db2. </para>
- </listitem>
- <listitem>
- <para> IBM DB2 supports both sequences and auto-incrementing
- keys. Therefore the arguments to
- <methodname>lastInsertId()</methodname> are
- optional. If you give no arguments, the Adapter returns
- the last value generated for an auto-increment key. If
- you give arguments, the Adapter returns the last value
- generated by the sequence named according to the
- convention ' <emphasis>table</emphasis> _
- <emphasis>column</emphasis> _seq'. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.mysqli">
- <title>MySQLi</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Mysqli'. </para>
- </listitem>
- <listitem>
- <para> This Adapter utilizes the <acronym>PHP</acronym>
- extension mysqli. </para>
- </listitem>
- <listitem>
- <para> MySQL does not support sequences, so
- <methodname>lastInsertId()</methodname> ignores its
- arguments and always returns the last value generated
- for an auto-increment key. The
- <methodname>lastSequenceId()</methodname> method
- returns <constant>NULL</constant> . </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.oracle">
- <title>Oracle</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Oracle'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extension oci8. </para>
- </listitem>
- <listitem>
- <para> Oracle does not support auto-incrementing keys, so
- you should specify the name of a sequence to
- <methodname>lastInsertId()</methodname> or
- <methodname>lastSequenceId()</methodname> . </para>
- </listitem>
- <listitem>
- <para> The Oracle extension does not support positional
- parameters. You must use named parameters. </para>
- </listitem>
- <listitem>
- <para> Currently the
- <constant>Zend_Db::CASE_FOLDING</constant> option is
- not supported by the Oracle adapter. To use this option
- with Oracle, you must use the <acronym>PDO</acronym> OCI
- adapter. </para>
- </listitem>
- <listitem>
- <para> By default, LOB fields are returned as OCI-Lob
- objects. You could retrieve them as string for all
- requests by using driver options
- <code>'lob_as_string'</code> or for particular
- request by using
- <methodname>setLobAsString(boolean)</methodname> on
- adapter or on statement. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.sqlsrv">
- <title>Microsoft SQL Server</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Sqlsrv'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extension sqlsrv </para>
- </listitem>
- <listitem>
- <para> Microsoft <acronym>SQL</acronym> Server does not
- support sequences, so
- <methodname>lastInsertId()</methodname> ignores
- primary key argument and returns the last value
- generated for an auto-increment key if a table name is
- specified or a last insert query returned id. The
- <methodname>lastSequenceId()</methodname> method
- returns <constant>NULL</constant> . </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Db_Adapter_Sqlsrv</classname> sets
- <constant>QUOTED_IDENTIFIER ON</constant>
- immediately after connecting to a <acronym>SQL</acronym>
- Server database. This makes the driver use the standard
- <acronym>SQL</acronym> identifier delimiter symbol (
- <emphasis>"</emphasis> ) instead of the proprietary
- square-brackets syntax <acronym>SQL</acronym> Server
- uses for delimiting identifiers. </para>
- </listitem>
- <listitem>
- <para> You can specify <property>driver_options</property>
- as a key in the options array. The value can be a
- anything from here <ulink
- url="http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx"
- >http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx</ulink>
- . </para>
- </listitem>
- <listitem>
- <para> You can use
- <methodname>setTransactionIsolationLevel()</methodname>
- to set isolation level for current connection. The value
- can be <constant>SQLSRV_TXN_READ_UNCOMMITTED</constant>
- , <constant>SQLSRV_TXN_READ_COMMITTED</constant> ,
- <constant>SQLSRV_TXN_REPEATABLE_READ</constant> ,
- <constant>SQLSRV_TXN_SNAPSHOT</constant> or
- <constant>SQLSRV_TXN_SERIALIZABLE</constant> .
- </para>
- </listitem>
- <listitem>
- <para> As of Zend Framework 1.9, the minimal supported build
- of the <acronym>PHP</acronym>
- <acronym>SQL</acronym> Server extension from Microsoft
- is 1.0.1924.0. and the <acronym>MSSQL</acronym> Server
- Native Client version 9.00.3042.00. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
- <title>PDO for IBM DB2 and Informix Dynamic Server (IDS)</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Ibm'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_ibm. </para>
- </listitem>
- <listitem>
- <para> You must use at least <acronym>PDO</acronym> _IBM
- extension version 1.2.2. If you have an earlier version
- of this extension, you must upgrade the
- <acronym>PDO</acronym> _IBM extension from
- <acronym>PECL</acronym> . </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
- <title>PDO Microsoft SQL Server</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Mssql'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_mssql. </para>
- </listitem>
- <listitem>
- <para> Microsoft <acronym>SQL</acronym> Server does not
- support sequences, so
- <methodname>lastInsertId()</methodname> ignores its
- arguments and always returns the last value generated
- for an auto-increment key. The
- <methodname>lastSequenceId()</methodname> method
- returns <constant>NULL</constant> . </para>
- </listitem>
- <listitem>
- <para> If you are working with unicode strings in an
- encoding other than UCS-2 (such as UTF-8), you may have
- to perform a conversion in your application code or
- store the data in a binary column. Please refer to
- <ulink url="http://support.microsoft.com/kb/232580"
- >Microsoft's Knowledge Base</ulink> for more
- information. </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Db_Adapter_Pdo_Mssql</classname> sets
- <constant>QUOTED_IDENTIFIER ON</constant>
- immediately after connecting to a <acronym>SQL</acronym>
- Server database. This makes the driver use the standard
- <acronym>SQL</acronym> identifier delimiter symbol (
- <code>"</code> ) instead of the proprietary
- square-brackets syntax <acronym>SQL</acronym> Server
- uses for delimiting identifiers. </para>
- </listitem>
- <listitem>
- <para> You can specify <code>pdoType</code> as a key in the
- options array. The value can be "mssql" (the default),
- "dblib", "freetds", or "sybase". This option affects the
- DSN prefix the adapter uses when constructing the DSN
- string. Both "freetds" and "sybase" imply a prefix of
- "sybase:", which is used for the <ulink
- url="http://www.freetds.org/">FreeTDS</ulink> set of
- libraries. See also <ulink
- url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php"
- >
- http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>
- for more information on the DSN prefixes used in this
- driver. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
- <title>PDO MySQL</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Mysql'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_mysql. </para>
- </listitem>
- <listitem>
- <para> MySQL does not support sequences, so
- <methodname>lastInsertId()</methodname> ignores its
- arguments and always returns the last value generated
- for an auto-increment key. The
- <methodname>lastSequenceId()</methodname> method
- returns <constant>NULL</constant> . </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
- <title>PDO Oracle</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Oci'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_oci. </para>
- </listitem>
- <listitem>
- <para> Oracle does not support auto-incrementing keys, so
- you should specify the name of a sequence to
- <methodname>lastInsertId()</methodname> or
- <methodname>lastSequenceId()</methodname> . </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
- <title>PDO PostgreSQL</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Pgsql'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_pgsql. </para>
- </listitem>
- <listitem>
- <para> PostgreSQL supports both sequences and
- auto-incrementing keys. Therefore the arguments to
- <methodname>lastInsertId()</methodname> are
- optional. If you give no arguments, the Adapter returns
- the last value generated for an auto-increment key. If
- you give arguments, the Adapter returns the last value
- generated by the sequence named according to the
- convention ' <emphasis>table</emphasis> _
- <emphasis>column</emphasis> _seq'. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
- <title>PDO SQLite</title>
- <itemizedlist>
- <listitem>
- <para> Specify this Adapter to the
- <methodname>factory()</methodname> method with the
- name 'Pdo_Sqlite'. </para>
- </listitem>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extensions pdo and pdo_sqlite. </para>
- </listitem>
- <listitem>
- <para> SQLite does not support sequences, so
- <methodname>lastInsertId()</methodname> ignores its
- arguments and always returns the last value generated
- for an auto-increment key. The
- <methodname>lastSequenceId()</methodname> method
- returns <constant>NULL</constant> . </para>
- </listitem>
- <listitem>
- <para> To connect to an SQLite2 database, specify
- <code>'sqlite2'=>true</code> in the array of
- parameters when creating an instance of the
- <classname>Pdo_Sqlite</classname> Adapter. </para>
- </listitem>
- <listitem>
- <para> To connect to an in-memory SQLite database, specify
- <code>'dbname'=>':memory:'</code> in the array of
- parameters when creating an instance of the
- <classname>Pdo_Sqlite</classname> Adapter. </para>
- </listitem>
- <listitem>
- <para> Older versions of the SQLite driver for
- <acronym>PHP</acronym> do not seem to support the
- PRAGMA commands necessary to ensure that short column
- names are used in result sets. If you have problems that
- your result sets are returned with keys of the form
- "tablename.columnname" when you do a join query, then
- you should upgrade to the current version of
- <acronym>PHP</acronym> . </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.firebird">
- <title>Firebird/Interbase</title>
- <itemizedlist>
- <listitem>
- <para> This Adapter uses the <acronym>PHP</acronym>
- extension php_interbase. </para>
- </listitem>
- <listitem>
- <para> Firebird/interbase does not support auto-incrementing
- keys, so you should specify the name of a sequence to
- <methodname>lastInsertId()</methodname> or
- <methodname>lastSequenceId()</methodname> . </para>
- </listitem>
- <listitem>
- <para> Currently the
- <constant>Zend_Db::CASE_FOLDING</constant> option is
- not supported by the Firebird/interbase adapter.
- Unquoted identifiers are automatically returned in upper
- case. </para>
- </listitem>
- <listitem>
- <para> Adapter name is
- <classname>ZendX_Db_Adapter_Firebird</classname> . </para>
- <para> Remember to use the param adapterNamespace with value
- <classname>ZendX_Db_Adapter</classname> . </para>
- <para> We recommend to update the gds32.dll (or linux
- equivalent) bundled with php, to the same version of the
- server. For Firebird the equivalent gds32.dll is
- fbclient.dll. </para>
- <para> By default all identifiers (tables names, fields) are
- returned in upper case. </para>
- </listitem>
- </itemizedlist>
- </sect3>
- </sect2>
- </sect1>
|