Zend_Db_Adapter.xml 98 KB

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