| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468 |
- <sect1 id="zend.db.adapter">
- <title>Zend_Db_Adapter</title>
- <para>
- Zend_Db y sus clases relacionadas proporcionan una interfaz
- simple de base de datos SQL para Zend Framework. El
- Zend_Db_Adapter es la clase base que se utiliza para conectar su
- aplicación PHP A una base de datos (RDBMS). Existen diferentes
- clases Adapters(Adaptador) para cada tipo de base de datos
- (RDBMS).
- </para>
- <para>
- Las clases
- <code>Adapters</code>
- de Zend_Db crean un puente entre las extensiones de base de
- datos de PHP hacia una interfaz común, para ayudarle a escribir
- aplicaciones PHP una sola vez y poder desplegar múltiples
- tipos de base de datos (RDBMS) 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>
- . Zend_Db proporciona clases Adaptadoras para los drivers PDO de
- los siguientes tipos de RDBMS:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- IBM DB2 e Informix Dynamic Server (IDS), usando la
- extensión PHP
- <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL, usando la extensión PHP
- <ulink url="http://www.php.net/pdo-mysql">
- pdo_mysql
- </ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Microsoft SQL Server, usando la extensión PHP
- <ulink url="http://www.php.net/pdo-mssql">
- pdo_mssql
- </ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle, usando la extensión PHP
- <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- PostgreSQL, usando la extensión PHP
- <ulink url="http://www.php.net/pdo-pgsql">
- pdo_pgsql
- </ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- SQLite, usando la extensión PHP
- <ulink url="http://www.php.net/pdo-sqlite">
- pdo_sqlite
- </ulink>
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Ademas, Zend_Db proporciona clases Adaptadoras que utilizan las
- extensiones de base de datos de PHP de los siguientes tipos:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- MySQL, usando la extensión PHP
- <ulink url="http://www.php.net/mysqli">mysqli</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle, usando la extensión PHP
- <ulink url="http://www.php.net/oci8">oci8</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- IBM DB2, usando la extensión PHP
- <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Firebird/Interbase, usando la extensión PHP
- <ulink url="http://www.php.net/ibase">
- php_interbase
- </ulink>
- </para>
- </listitem>
- </itemizedlist>
- <note>
- <para>
- Cada Zend_Db_Adaptador utiliza una extensión PHP. Se debe de
- tener habilitada la respectiva extensión en su entorno PHP
- para utilizar un Zend_Db_Adapter. Por ejemplo, si se utiliza
- una clase Zend_Db_Adapter basada en PDO, tiene que
- habilitar tanto la extensión PDO como el driver PDO 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 (RDBMS) desde su
- aplicación PHP.
- </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 role="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 Factory de Zend_Db</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
- <code>Zend_Db::factory()</code>
- . 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
- 'Pdo_Mysql' corresponde a la clase
- Zend_Db_Adapter_Pdo_Mysql. 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 role="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
- Zend_Db_Adapter_Abstract, pero no nombra su clase con el prefijo
- de paquete "Zend_Db_Adapter", se puede utilizar el método
- <code>factory()</code>
- 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 role="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
- <code>factory()</code>
- 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
- <code>adapter</code>
- , conteniendo la cadena que da nombre al nombre base de la
- clase de adaptador. Opcionalmente, el objeto puede
- contener una propiedad llamada
- <code>params</code>
- , con subpropiedades correspondientes a nombres de parámetros
- del adaptador. Esto es usado sólo si el segundo
- argumento del método <code>factory()</code> 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 Zend_Config 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 role="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
- <code>factory()</code>
- 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 Zend_Config,
- 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 Zend_Db.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis role="strong">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 PHP,
- usted puede utilizar 'localhost' o '127.0.0.1'.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">username</emphasis>
- : identificador de cuenta para autenticar una conexión al
- servidor RDBMS.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">password</emphasis>
- : la contraseña de la cuenta para la autenticación de credenciales
- de conexión con el servidor RDBMS
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">dbname</emphasis>
- : nombre de la base de datos en el servidor RDBMS.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">port</emphasis>
- : algunos servidores RDBMS 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 PHP se conecta, para que concuerde el puerto
- configurado en el servidor RDBMS.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">options</emphasis>
- : este parámetro es un array asociativo de
- opciones que son genéricas a todas las clases Zend_Db_Adapter.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">
- 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 PDO.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">
- adapterNamespace
- </emphasis>
- : nombre de la parte inicial del nombre de las clase para el
- adaptador, en lugar de 'Zend_Db_Adapter'. Utilice
- esto si usted necesita usar el método
- <code>factory()</code>
- 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
- <code>Zend_Db::CASE_FOLDING</code>
- . Este corresponde al atributo
- <code>ATTR_CASE</code>
- en los drivers de base de datos PDO e IBM DB2,
- ajustando la sensibilidad de las claves tipo cadena en los resultados
- de consultas. La opción toma los valores
- <code>Zend_Db::CASE_NATURAL</code>
- (el predeterminado),
- <code>Zend_Db::CASE_UPPER</code>
- , y
- <code>Zend_Db::CASE_LOWER</code>
- .
- </para>
- <programlisting role="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
- <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
- . Si el valor es
- <code>true</code>
- (el predeterminado), los identificadores como nombres de tabla,
- nombres de columna, e incluso los alias son delimitados en la
- sintaxis SQL generada por el Adatador del objeto.
- Esto hace que sea sencillo utilizar identificadores que contengan
- palabras reservadas de SQL, o caracteres especiales. Si el valor es
- <code>false</code>
- , los identificadores no son delimitados automáticamente. Si
- usted necesita delimitar identificadores, debe hacer usted mismo
- utilizando el método
- <code>quoteIdentifier()</code>
- .
- </para>
- <programlisting role="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 role="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>
- </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 RDBMS 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
- RDBMS, use the
- <code>getConnection()</code>
- method. This method returns an object for the connection
- as represented by the respective PHP database extension.
- For example, if you use any of the Adapter classes for
- PDO drivers, then
- <code>getConnection()</code>
- returns the PDO 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
- RDBMS 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>
- <example id="zend.db.adapter.connecting.getconnection.example">
- <title>Handling connection exceptions</title>
- <programlisting role="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 Zend_Db, 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 role="strong">accounts</emphasis>
- almacena información sobre cada usuario que hace el
- seguimiento de bugs.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">products</emphasis>
- almacena información sobre cada producto para el que
- pueden registrarse bugs.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">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 role="strong">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 SQL 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 Zend_Db.
- </para>
- <programlisting role="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"></inlinegraphic>
- </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 SQL SELECT query and retrieve its results
- in one step using the
- <code>fetchAll()</code>
- 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
- <code>fetchAll()</code>
- is an array of values to substitute for parameter
- placeholders in the SQL statement.
- </para>
- <example id="zend.db.adapter.select.fetchall.example">
- <title>Using fetchAll()</title>
- <programlisting role="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,
- <code>fetchAll()</code>
- 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
- <code>setFetchMode()</code>
- method. The modes supported are identified by constants:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis role="strong">
- Zend_Db::FETCH_ASSOC
- </emphasis>
- : return data in an array of associative arrays.
- The array keys are column names, as strings.
- This is the default fetch mode for
- Zend_Db_Adapter 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
- RDBMS server. You can specify the case for these
- strings, using the
- <code>Zend_Db::CASE_FOLDING</code>
- option. Specify this when instantiating the
- Adapter. See
- <xref linkend="zend.db.adapter.connecting.parameters.example1"></xref>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis role="strong">
- Zend_Db::FETCH_NUM
- </emphasis>
- : 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>
- <emphasis role="strong">
- Zend_Db::FETCH_BOTH
- </emphasis>
- : 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>
- <emphasis role="strong">
- Zend_Db::FETCH_COLUMN
- </emphasis>
- : 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>
- <emphasis role="strong">
- Zend_Db::FETCH_OBJ
- </emphasis>
- : return data in an array of objects. The
- default class is the PHP 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 role="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
- <code>fetchAssoc()</code>
- 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 role="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
- <code>fetchCol()</code>
- 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"></xref>
- .
- </para>
- <example id="zend.db.adapter.select.fetchcol.example">
- <title>Using fetchCol()</title>
- <programlisting role="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
- <code>fetchPairs()</code>
- 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 role="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
- <code>fetchRow()</code>
- 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 role="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
- <code>fetchOne()</code>
- method is like a combination of
- <code>fetchRow()</code>
- with
- <code>fetchCol()</code>
- , 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 role="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
- <code>insert()</code>
- 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 to a table</title>
- <programlisting role="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 SQL 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
- NULL 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
- SQL 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 SQL expression and therefore should not be
- quoted, pass the value in the data array as an object of
- type Zend_Db_Expr instead of a plain string.
- </para>
- <example id="zend.db.adapter.write.insert.example2">
- <title>Inserting expressions to a table</title>
- <programlisting role="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 RDBMS 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
- <code>insert()</code>
- 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
- <code>lastInsertId()</code>
- 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 role="php"><![CDATA[
- $db->insert('bugs', $data);
- // return the last value generated by an auto-increment column
- $id = $db->lastInsertId();
- ]]>
- </programlisting>
- </example>
- <para>
- Some RDBMS brands support a sequence object, which
- generates unique values to serve as primary key values.
- To support sequences, the
- <code>lastInsertId()</code>
- 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 role="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
- <code>lastSequenceId()</code>
- 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 role="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 RDBMS brands that don't support sequences, including
- MySQL, Microsoft SQL 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 RDBMS brands, the lastSequenceId()
- method always returns
- <code>null</code>
- .
- </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
- RDBMS 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 RDBMS 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
- <code>update()</code>
- 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"></xref>
- for information on using SQL expressions in the data
- array.
- </para>
- <para>
- The third argument is a string containing an SQL
- 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"></xref>
- 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 role="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
- <code>AND</code>
- operators.
- </para>
- <example id="zend.db.adapter.write.update.example-array">
- <title>
- Updating rows using an array of expressions
- </title>
- <programlisting role="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
- <code>delete()</code>
- method. This method takes two arguments: the first is a
- string naming the table.
- </para>
- <para>
- The second argument is a string containing an SQL
- 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"></xref>
- 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 role="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
- <code>AND</code>
- operators.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.quoting">
- <title>Quoting Values and Identifiers</title>
- <para>
- When you form SQL queries, often it is the case that you
- need to include the values of PHP variables in SQL
- 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 SQL. For example, notice the
- imbalanced quote characters in the following query:
- <programlisting role="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 PHP variable through the use of an
- HTTP parameter or other mechanism, they might be able to
- make your SQL 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 Zend_Db Adapter class provides convenient functions to
- help you reduce vulnerabilities to SQL Injection attacks in
- your PHP code. The solution is to escape special characters
- such as quotes in PHP values before they are interpolated
- into your SQL strings. This protects against both accidental
- and deliberate manipulation of SQL strings by PHP variables
- that contain special characters.
- </para>
- <sect3 id="zend.db.adapter.quoting.quote">
- <title>
- Using
- <code>quote()</code>
- </title>
- <para>
- The
- <code>quote()</code>
- method accepts a single argument, a scalar string value.
- It returns the value with special characters escaped in
- a manner appropriate for the RDBMS you are using, and
- surrounded by string value delimiters. The standard SQL
- string value delimiter is the single-quote (
- <code>'</code>
- ).
- </para>
- <example id="zend.db.adapter.quoting.quote.example">
- <title>Using quote()</title>
- <programlisting role="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
- <code>quote()</code>
- 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 SQL 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 SQL implementations,
- assuming
- <code>intColumn</code>
- has a SQL datatype of
- <code>INTEGER</code>
- <programlisting role="php"><![CDATA[
- SELECT * FROM atable WHERE intColumn = '123'
- ]]>
- </programlisting>
- </para>
- <para>
- You can use the optional second argument to the
- <code>quote()</code>
- method to apply quoting selectively for the SQL datatype
- you specify.
- </para>
- <example id="zend.db.adapter.quoting.quote.example-2">
- <title>Using quote() with a SQL type</title>
- <programlisting role="php"><![CDATA[
- $value = '1234';
- $sql = 'SELECT * FROM atable WHERE intColumn = '
- . $db->quote($value, 'INTEGER');
- ]]>
- </programlisting>
- </example>
- <para>
- Each Zend_Db_Adapter class has encoded the names of
- numeric SQL datatypes for the respective brand of RDBMS.
- You can also use the constants
- <code>Zend_Db::INT_TYPE</code>
- ,
- <code>Zend_Db::BIGINT_TYPE</code>
- , and
- <code>Zend_Db::FLOAT_TYPE</code>
- to write code in a more RDBMS-independent way.
- </para>
- <para>
- Zend_Db_Table specifies SQL types to
- <code>quote()</code>
- automatically when generating SQL queries that reference
- a table's key columns.
- </para>
- </sect3>
- <sect3 id="zend.db.adapter.quoting.quote-into">
- <title>
- Using
- <code>quoteInto()</code>
- </title>
- <para>
- The most typical usage of quoting is to interpolate a
- PHP variable into a SQL expression or statement. You can
- use the
- <code>quoteInto()</code>
- 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 PHP variable
- that should be substituted for that placeholder.
- </para>
- <para>
- The placeholder symbol is the same symbol used by many
- RDBMS brands for positional parameters, but the
- <code>quoteInto()</code>
- 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 SQL
- string and the parameters as the statement is parsed in
- the RDBMS server.
- </para>
- <example id="zend.db.adapter.quoting.quote-into.example">
- <title>Using quoteInto()</title>
- <programlisting role="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
- <code>quoteInto()</code>
- to specify the SQL 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 role="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
- <code>quoteIdentifier()</code>
- </title>
- <para>
- Values are not the only part of SQL syntax that might
- need to be variable. If you use PHP variables to name
- tables, columns, or other identifiers in your SQL
- statements, you might need to quote these strings too.
- By default, SQL identifiers have syntax rules like PHP
- 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 SQL
- syntax, and should not be used as identifiers.
- </para>
- <para>
- However, SQL has a feature called
- <emphasis>delimited identifiers</emphasis>
- , which allows broader choices for the spelling of
- identifiers. If you enclose a SQL 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 SQL
- reserved words if you enclose them in identifier
- delimiters.
- </para>
- <para>
- The
- <code>quoteIdentifier()</code>
- method works like
- <code>quote()</code>
- , but it applies the identifier delimiter characters to
- the string according to the type of Adapter you use. For
- example, standard SQL uses double-quotes (
- <code>"</code>
- ) for identifier delimiters, and most RDBMS brands use
- that symbol. MySQL uses back-quotes (
- <code>`</code>
- ) by default. The
- <code>quoteIdentifier()</code>
- method also escapes special characters within the string
- argument.
- </para>
- <example id="zend.db.adapter.quoting.quote-identifier.example">
- <title>Using quoteIdentifier()</title>
- <programlisting role="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>
- SQL 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 SQL is generated within Zend_Db
- classes, the default is that all identifiers are
- delimited automatically. You can change this behavior
- with the option
- <code>Zend_Db::AUTO_QUOTE_IDENTIFIERS</code>
- . Specify this when instantiating the Adapter. See
- <xref linkend="zend.db.adapter.connecting.parameters.example2"></xref>
- .
- </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 SQL statement has been executed. By default, all
- Zend_Db 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 SQL queries are
- included in a single group that is committed (or rolled
- back) as a single operation. Use the
- <code>beginTransaction()</code>
- method to initiate a transaction. Subsequent SQL statements
- are executed in the context of the same transaction until
- you resolve it explicitly.
- </para>
- <para>
- To resolve the transaction, use either the
- <code>commit()</code>
- or
- <code>rollBack()</code>
- methods. The
- <code>commit()</code>
- 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
- <code>rollBack()</code>
- 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,
- <code>Zend_Db_Adapter</code>
- returns to auto-commit mode until you call
- <code>beginTransaction()</code>
- again.
- </para>
- <example id="zend.db.adapter.transactions.example">
- <title>Managing a transaction to ensure consistency</title>
- <programlisting role="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
- <code>listTables()</code>
- method returns an array of strings, naming all tables in the
- current database.
- </para>
- <para>
- The
- <code>describeTable()</code>
- 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>SCHEMA_NAME</entry>
- <entry>(string)</entry>
- <entry>
- Name of the database schema in which this
- table exists.
- </entry>
- </row>
- <row>
- <entry>TABLE_NAME</entry>
- <entry>(string)</entry>
- <entry>
- Name of the table to which this column
- belongs.
- </entry>
- </row>
- <row>
- <entry>COLUMN_NAME</entry>
- <entry>(string)</entry>
- <entry>Name of the column.</entry>
- </row>
- <row>
- <entry>COLUMN_POSITION</entry>
- <entry>(integer)</entry>
- <entry>
- Ordinal position of the column in the table.
- </entry>
- </row>
- <row>
- <entry>DATA_TYPE</entry>
- <entry>(string)</entry>
- <entry>
- RDBMS name of the datatype of the column.
- </entry>
- </row>
- <row>
- <entry>DEFAULT</entry>
- <entry>(string)</entry>
- <entry>
- Default value for the column, if any.
- </entry>
- </row>
- <row>
- <entry>NULLABLE</entry>
- <entry>(boolean)</entry>
- <entry>
- True if the column accepts SQL NULLs, false
- if the column has a NOT NULL constraint.
- </entry>
- </row>
- <row>
- <entry>LENGTH</entry>
- <entry>(integer)</entry>
- <entry>
- Length or size of the column as reported by
- the RDBMS.
- </entry>
- </row>
- <row>
- <entry>SCALE</entry>
- <entry>(integer)</entry>
- <entry>
- Scale of SQL NUMERIC or DECIMAL type.
- </entry>
- </row>
- <row>
- <entry>PRECISION</entry>
- <entry>(integer)</entry>
- <entry>
- Precision of SQL NUMERIC or DECIMAL type.
- </entry>
- </row>
- <row>
- <entry>UNSIGNED</entry>
- <entry>(boolean)</entry>
- <entry>
- True if an integer-based type is reported as
- UNSIGNED.
- </entry>
- </row>
- <row>
- <entry>PRIMARY</entry>
- <entry>(boolean)</entry>
- <entry>
- True if the column is part of the primary
- key of this table.
- </entry>
- </row>
- <row>
- <entry>PRIMARY_POSITION</entry>
- <entry>(integer)</entry>
- <entry>
- Ordinal position (1-based) of the column in
- the primary key.
- </entry>
- </row>
- <row>
- <entry>IDENTITY</entry>
- <entry>(boolean)</entry>
- <entry>
- True if the column uses an auto-generated
- value.
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <note>
- <title>
- How the IDENTITY metadata field relates to specific
- RDBMS
- </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>
- <code>IDENTITY</code>
- - DB2, MSSQL
- </para>
- </listitem>
- <listitem>
- <para>
- <code>AUTO_INCREMENT</code>
- - MySQL
- </para>
- </listitem>
- <listitem>
- <para>
- <code>SERIAL</code>
- - PostgreSQL
- </para>
- </listitem>
- <listitem>
- <para>
- <code>SEQUENCE</code>
- - Oracle
- </para>
- </listitem>
- </itemizedlist>
- </note>
- <para>
- If no table exists matching the table name and optional
- schema name specified, then
- <code>describeTable()</code>
- 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.
- PHP 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 PHP script that
- initiates many database connections, you might need to close
- the connection, to avoid exhausting the capacity of your
- RDBMS server. You can use the Adapter's
- <code>closeConnection()</code>
- method to explicitly close the underlying database
- connection.
- </para>
- <example id="zend.db.adapter.closing.example">
- <title>Closing a database connection</title>
- <programlisting role="php"><![CDATA[
- $db->closeConnection();
- ]]>
- </programlisting>
- </example>
- <note>
- <title>Does Zend_Db support persistent connections?</title>
- <para>
- The usage of persistent connections is not supported or
- encouraged in Zend_Db.
- </para>
- <para>
- Using persistent connections can cause an excess of idle
- connections on the RDBMS 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 RDBMS 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 PHP request.
- </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 PHP database
- extension. Some of these extensions may offer features that
- are not surfaced by methods of Zend_Db_Adapter_Abstract.
- </para>
- <para>
- For example, all SQL statements run by Zend_Db 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, SQL
- 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 PHP database extensions provide a method to execute SQL
- statements without preparing them. For example, in PDO, this
- method is
- <code>exec()</code>
- . You can access the connection object in the PHP 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 role="php"><![CDATA[
- $result = $db->getConnection()->exec('DROP TABLE bugs');
- ]]>
- </programlisting>
- </example>
- <para>
- Similarly, you can access other methods or properties that
- are specific to PHP 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 RDBMS.
- </para>
- <para>
- In future versions of Zend_Db, there will be opportunities
- to add method entry points for functionality that is common
- to the supported PHP database extensions. This will not
- affect backward compatibility.
- </para>
- </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 PHP extension ibm_db2.
- </para>
- </listitem>
- <listitem>
- <para>
- IBM DB2 supports both sequences and
- auto-incrementing keys. Therefore the arguments
- to
- <code>lastInsertId()</code>
- 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
- <code>factory()</code>
- method with the name 'Mysqli'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter utilizes the PHP extension mysqli.
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL does not support sequences, so
- <code>lastInsertId()</code>
- ignores its arguments and always returns the
- last value generated for an auto-increment key.
- The
- <code>lastSequenceId()</code>
- method returns
- <code>null</code>
- .
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.oracle">
- <title>Oracle</title>
- <itemizedlist>
- <listitem>
- <para>
- Specify this Adapter to the
- <code>factory()</code>
- method with the name 'Oracle'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extension oci8.
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle does not support auto-incrementing keys,
- so you should specify the name of a sequence to
- <code>lastInsertId()</code>
- or
- <code>lastSequenceId()</code>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- The Oracle extension does not support positional
- parameters. You must use named parameters.
- </para>
- </listitem>
- <listitem>
- <para>
- Currently the
- <code>Zend_Db::CASE_FOLDING</code>
- option is not supported by the Oracle adapter.
- To use this option with Oracle, you must use the
- PDO OCI adapter.
- </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
- <code>factory()</code>
- method with the name 'Pdo_Ibm'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extensions pdo and
- pdo_ibm.
- </para>
- </listitem>
- <listitem>
- <para>
- You must use at least PDO_IBM extension version
- 1.2.2. If you have an earlier version of this
- extension, you must upgrade the PDO_IBM
- extension from PECL.
- </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
- <code>factory()</code>
- method with the name 'Pdo_Mssql'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extensions pdo and
- pdo_mssql.
- </para>
- </listitem>
- <listitem>
- <para>
- Microsoft SQL Server does not support sequences,
- so
- <code>lastInsertId()</code>
- ignores its arguments and always returns the
- last value generated for an auto-increment key.
- The
- <code>lastSequenceId()</code>
- method returns
- <code>null</code>
- .
- </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>
- Zend_Db_Adapter_Pdo_Mssql sets
- <code>QUOTED_IDENTIFIER ON</code>
- immediately after connecting to a SQL Server
- database. This makes the driver use the standard
- SQL identifier delimiter symbol (
- <code>"</code>
- ) instead of the proprietary square-brackets
- syntax SQL 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
- <code>factory()</code>
- method with the name 'Pdo_Mysql'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extensions pdo and
- pdo_mysql.
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL does not support sequences, so
- <code>lastInsertId()</code>
- ignores its arguments and always returns the
- last value generated for an auto-increment key.
- The
- <code>lastSequenceId()</code>
- method returns
- <code>null</code>
- .
- </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
- <code>factory()</code>
- method with the name 'Pdo_Oci'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP 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
- <code>lastInsertId()</code>
- or
- <code>lastSequenceId()</code>
- .
- </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
- <code>factory()</code>
- method with the name 'Pdo_Pgsql'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extensions pdo and
- pdo_pgsql.
- </para>
- </listitem>
- <listitem>
- <para>
- PostgreSQL supports both sequences and
- auto-incrementing keys. Therefore the arguments
- to
- <code>lastInsertId()</code>
- 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
- <code>factory()</code>
- method with the name 'Pdo_Sqlite'.
- </para>
- </listitem>
- <listitem>
- <para>
- This Adapter uses the PHP extensions pdo and
- pdo_sqlite.
- </para>
- </listitem>
- <listitem>
- <para>
- SQLite does not support sequences, so
- <code>lastInsertId()</code>
- ignores its arguments and always returns the
- last value generated for an auto-increment key.
- The
- <code>lastSequenceId()</code>
- method returns
- <code>null</code>
- .
- </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 Pdo_Sqlite 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 Pdo_Sqlite Adapter.
- </para>
- </listitem>
- <listitem>
- <para>
- Older versions of the SQLite driver for PHP 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 PHP.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.firebird">
- <title>Firebird/Interbase</title>
- <itemizedlist>
- <listitem>
- <para>
- This Adapter uses the PHP 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
- <code>lastInsertId()</code>
- or
- <code>lastSequenceId()</code>
- .
- </para>
- </listitem>
- <listitem>
- <para>
- Currently the
- <code>Zend_Db::CASE_FOLDING</code>
- option is not supported by the
- Firebird/interbase adapter. Unquoted identifiers
- are automatically returned in upper case.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|