Zend_Db_Adapter.xml 103 KB

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