Zend_Db_Adapter.xml 89 KB

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