Zend_Db_Adapter.xml 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287
  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> i powiązane z nim klasy udostępniają prosty interfejs
  7. dla baz danych <acronym>SQL</acronym> z poziomu Zend Framework. Klasa
  8. <classname>Zend_Db_Adapter</classname> jest podstawowym komponentem potrzebnym by
  9. połączyć aplikację PHP z systemem zarządzania bazą danych (<acronym>RDBMS</acronym>).
  10. Dla każdego rodzaju bazy danych istnieje oddzielna klasa adaptera
  11. <classname>Zend_Db</classname>.
  12. </para>
  13. <para>
  14. Adaptery <classname>Zend_Db</classname> tworzą połączenie pomiędzy rozszerzeniami
  15. <acronym>PHP</acronym> dla konkretnych rodzajów baz danych a wspólnym interfejsem,
  16. dzięki czemu można napisać aplikację raz i w nieskomplikowany sposób uruchamiać
  17. ją z wieloma rodzajami <acronym>RDBMS</acronym>
  18. </para>
  19. <para>
  20. Interfejs klasy adaptera jest podobny do interfejsu rozszerzenia
  21. <ulink url="http://www.php.net/pdo">PHP Data Objects</ulink>. <classname>Zend_Db</classname>
  22. zawiera klasy adapterów dla sterowników <acronym>PDO</acronym> następujących rodzajów
  23. baz danych:
  24. </para>
  25. <itemizedlist>
  26. <listitem>
  27. <para>
  28. IBM DB2 oraz Informix Dynamic Server (IDS), poprzez rozszerzenie <acronym>PHP</acronym>
  29. <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>.
  30. </para>
  31. </listitem>
  32. <listitem>
  33. <para>
  34. MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
  35. <ulink url="http://www.php.net/pdo-mysql">pdo_mysql</ulink>
  36. </para>
  37. </listitem>
  38. <listitem>
  39. <para>
  40. Microsoft <acronym>SQL</acronym> Server, używając rozszerzenia <acronym>PHP</acronym>
  41. <ulink url="http://www.php.net/pdo-dblib">pdo_dblib</ulink>
  42. </para>
  43. </listitem>
  44. <listitem>
  45. <para>
  46. Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
  47. <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
  48. </para>
  49. </listitem>
  50. <listitem>
  51. <para>
  52. PostgreSQL, poprzez rozszerzenie <acronym>PHP</acronym>
  53. <ulink url="http://www.php.net/pdo-pgsql">pdo_pgsql</ulink>
  54. </para>
  55. </listitem>
  56. <listitem>
  57. <para>
  58. SQLite, używając rozszerzenia <acronym>PHP</acronym>
  59. <ulink url="http://www.php.net/pdo-sqlite">pdo_sqlite</ulink>
  60. </para>
  61. </listitem>
  62. </itemizedlist>
  63. <para>
  64. Dodatkowo <classname>Zend_Db</classname> dostarcza klas adapterów korzystających
  65. z rozszerzeń <acronym>PHP</acronym> dla następujących rodzajów
  66. baz danych:
  67. </para>
  68. <itemizedlist>
  69. <listitem>
  70. <para>
  71. MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
  72. <ulink url="http://www.php.net/mysqli">mysqli</ulink>
  73. </para>
  74. </listitem>
  75. <listitem>
  76. <para>
  77. Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
  78. <ulink url="http://www.php.net/oci8">oci8</ulink>
  79. </para>
  80. </listitem>
  81. <listitem>
  82. <para>
  83. IBM DB2 oraz DB2/i5, poprzez rozszerzenie <acronym>PHP</acronym>
  84. <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
  85. </para>
  86. </listitem>
  87. <listitem>
  88. <para>
  89. Firebird/Interbase, poprzez rozszerzenie <acronym>PHP</acronym>
  90. <ulink url="http://www.php.net/ibase">php_interbase</ulink>
  91. </para>
  92. </listitem>
  93. </itemizedlist>
  94. <note>
  95. <para>
  96. Każdy adapter <classname>Zend_Db</classname> używa określonego rozszerzenia
  97. <acronym>PHP</acronym>. Aby użyć adaptera należy mieć zainstalowane i włączone
  98. odpowiadające mu rozszerzenie <acronym>PHP</acronym>. Np. aby użyć dowolnego
  99. adaptera <acronym>PDO</acronym> <classname>Zend_Db</classname>, wymagane jest
  100. posiadanie włączonego rozszerzenia <acronym>PDO</acronym> oraz sterownika dla
  101. danego rodzaju <acronym>RDBMS</acronym>.
  102. </para>
  103. </note>
  104. <sect2 id="zend.db.adapter.connecting">
  105. <title>Połączenie z bazą danych za pomocą adaptera</title>
  106. <para>
  107. Ta część opisuje jak tworzy się instancję adaptera bazy danych. Jest to odpowiednik
  108. połączenia z bazą danych w aplikacji <acronym>PHP</acronym>.
  109. </para>
  110. <sect3 id="zend.db.adapter.connecting.constructor">
  111. <title>Użycie konstruktora adaptera Zend_Db</title>
  112. <para>
  113. Można utworzyć instancję adaptera za pomocą konstruktora. Przyjmuje on
  114. pojedynczy argument - tablicę parametrów używanych do deklaracji połączenia.
  115. </para>
  116. <example id="zend.db.adapter.connecting.constructor.example">
  117. <title>Użycie konstruktora adaptera</title>
  118. <programlisting language="php"><![CDATA[
  119. $db = new Zend_Db_Adapter_Pdo_Mysql(array(
  120. 'host' => '127.0.0.1',
  121. 'username' => 'webuser',
  122. 'password' => 'xxxxxxxx',
  123. 'dbname' => 'test'
  124. ));
  125. ]]></programlisting>
  126. </example>
  127. </sect3>
  128. <sect3 id="zend.db.adapter.connecting.factory">
  129. <title>Użycie fabryki Zend_Db</title>
  130. <para>
  131. Alternatywą w stosunku do bezpośredniego używania konstruktora jest utworzenie
  132. instancji adaptera za pomocą statycznej metody
  133. <methodname>Zend_Db::factory()</methodname>. Ta metoda dynamicznie ładuje plik
  134. klasy adaptera używając
  135. <link linkend="zend.loader.load.class">Zend_Loader::loadClass()</link>.
  136. </para>
  137. <para>
  138. Pierwszy argument metody to łańcuch znaków, który wyznacza nazwę bazową klasy
  139. adaptera. Np. string '<classname>Pdo_Mysql</classname>' odpowiada klasie
  140. <classname>Zend_Db_Adapter_Pdo_Mysql</classname>. Drugi argument to ta sama
  141. tablica parametrów, którą należało podać adapterowi konstruktora.
  142. </para>
  143. <example id="zend.db.adapter.connecting.factory.example">
  144. <title>Użycie metody fabryki adaptera</title>
  145. <programlisting language="php"><![CDATA[
  146. // Poniższa instrukcja jest zbędna ponieważ plik z klasą
  147. // Zend_Db_Adapter_Pdo_Mysql zostanie załadowany przez fabrykę
  148. // Zend_Db
  149. // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
  150. // Załaduj klasę Zend_Db_Adapter_Pdo_Mysql automatycznie
  151. // i utwórz jej instancję
  152. $db = Zend_Db::factory('Pdo_Mysql', array(
  153. 'host' => '127.0.0.1',
  154. 'username' => 'webuser',
  155. 'password' => 'xxxxxxxx',
  156. 'dbname' => 'test'
  157. ));
  158. ]]></programlisting>
  159. </example>
  160. <para>
  161. Jeśli jest zdefiniowana własna klasa dziedzicząca po
  162. <classname>Zend_Db_Adapter_Abstract</classname> ale jej nazwa nie zawiera
  163. "<classname>Zend_Db_Adapter</classname>", można użyć metody
  164. <methodname>factory()</methodname> do załadowania adaptera jedynie jeśli
  165. poda się swój prefiks nazwy adaptera z kluczem 'adapterNamespace' do
  166. argumentu zawierającego parametry połączenia.
  167. </para>
  168. <example id="zend.db.adapter.connecting.factory.example2">
  169. <title>Użycie metody fabryki dla własnej klasy adaptera</title>
  170. <programlisting language="php"><![CDATA[
  171. // Nie trzeba ładować pliku klasy adaptera
  172. // bo robi to metoda fabryki Zend_Db
  173. // Załadowanie klasy MyProject_Db_Adapter_Pdo_Mysql automatycznie
  174. // i utworzenie jej instancji
  175. $db = Zend_Db::factory('Pdo_Mysql', array(
  176. 'host' => '127.0.0.1',
  177. 'username' => 'webuser',
  178. 'password' => 'xxxxxxxx',
  179. 'dbname' => 'test',
  180. 'adapterNamespace' => 'MyProject_Db_Adapter'
  181. ));
  182. ]]></programlisting>
  183. </example>
  184. </sect3>
  185. <sect3 id="zend.db.adapter.connecting.factory-config">
  186. <title>Użycie Zend_Config z fabryką Zend_Db</title>
  187. <para>
  188. Każdy z argumentów metody <methodname>factory()</methodname> może również zostać
  189. podany w formie obiektu klasy <link linkend="zend.config">Zend_Config</link>.
  190. </para>
  191. <para>
  192. Jeśli pierwszy argument jest obiektem <classname>Zend_Config</classname> to wymagane
  193. jest aby posiadał właściwość o nazwie <property>adapter</property>, w której będzie
  194. zapisany łańcuch znaków określający nazwę bazową klasy adaptera. Opcjonalnie, obiekt
  195. ten może zawierać właściwość '<property>params</property>' z właściwościami potomnymi
  196. odpowiadającymi nazwom parametrów adaptera. Będą one użyte jedynie w przypadku braku
  197. drugiego argumentu metody <methodname>factory()</methodname>.
  198. </para>
  199. <example id="zend.db.adapter.connecting.factory.example1">
  200. <title>Użycie metody fabryki adaptera z obiektem Zend_Config</title>
  201. <para>
  202. W poniższym przykładzie, obiekt <classname>Zend_Config</classname> jest utworzony
  203. z tablicy. Można również załadować dane z pliku zewnętrznego poprzez klasy
  204. <link linkend="zend.config.adapters.ini">Zend_Config_Ini</link> oraz
  205. <link linkend="zend.config.adapters.xml">Zend_Config_Xml</link>.
  206. </para>
  207. <programlisting language="php"><![CDATA[
  208. $config = new Zend_Config(
  209. array(
  210. 'database' => array(
  211. 'adapter' => 'Mysqli',
  212. 'params' => array(
  213. 'host' => '127.0.0.1',
  214. 'dbname' => 'test',
  215. 'username' => 'webuser',
  216. 'password' => 'secret',
  217. )
  218. )
  219. )
  220. );
  221. $db = Zend_Db::factory($config->database);
  222. ]]></programlisting>
  223. </example>
  224. <para>
  225. Drugi argument metody <methodname>factory()</methodname> może stanowić tablicę
  226. asocjacyjną zawierającą wartości odpowiadające parametrom adaptera. Ten argument
  227. jest opcjonalny. Jeśli pierwszy argument jest obiektem klasy
  228. <classname>Zend_Config</classname> to powinien zawierać wszystkie parametry a
  229. drugi argument jest ignorowany.
  230. </para>
  231. </sect3>
  232. <sect3 id="zend.db.adapter.connecting.parameters">
  233. <title>Parametry adaptera</title>
  234. <para>
  235. Poniższa lista opisuje parametry wspólne dla klas adapterów
  236. <classname>Zend_Db</classname>.
  237. </para>
  238. <itemizedlist>
  239. <listitem>
  240. <para>
  241. <emphasis>host</emphasis>:
  242. łańcuch znaków zawierający nazwę hosta lub adres IP serwera bazy danych.
  243. Jeśli baza danych jest uruchomiona na tej samej maszynie co aplikacja to
  244. można tu umieścić 'localhost' lub '127.0.0.1'.
  245. </para>
  246. </listitem>
  247. <listitem>
  248. <para>
  249. <emphasis>username</emphasis>:
  250. identyfikator użytkownika używany do autoryzacji połączenia z serwerem
  251. bazy danych.
  252. </para>
  253. </listitem>
  254. <listitem>
  255. <para>
  256. <emphasis>password</emphasis>:
  257. hasło użytkownika używane do autoryzacji połączenia z serwerem
  258. bazy danych.
  259. </para>
  260. </listitem>
  261. <listitem>
  262. <para>
  263. <emphasis>dbname</emphasis>:
  264. nazwa instancji bazy danych na serwerze.
  265. </para>
  266. </listitem>
  267. <listitem>
  268. <para>
  269. <emphasis>port</emphasis>:
  270. niektóre serwery bazy danych używają do komunikacji numeru portu określonego
  271. przez administratora. Ten parametr pozwala na ustawienie numeru portu przez
  272. który aplikacja <acronym>PHP</acronym> się łączy tak aby zgadzał się z tym
  273. ustawionym na serwerze bazy danych.
  274. </para>
  275. </listitem>
  276. <listitem>
  277. <para>
  278. <emphasis>charset</emphasis>:
  279. określenie zestawu znaków używanego podczas połączenia.
  280. </para>
  281. </listitem>
  282. <listitem>
  283. <para>
  284. <emphasis>options</emphasis>:
  285. ten parametr to tablica asocjacyjna opcji obsługiwanych przez wszystkie
  286. klasy <classname>Zend_Db_Adapter</classname>.
  287. </para>
  288. </listitem>
  289. <listitem>
  290. <para>
  291. <emphasis>driver_options</emphasis>:
  292. ten parametr to tablica asocjacyjna zawierająca dodatkowe opcje
  293. specyficzne dla każdego rozszerzenia bazy danych. Typowym przykładem
  294. użycia tego parametru jest zbiór atrybutów sterownika <acronym>PDO</acronym>.
  295. </para>
  296. </listitem>
  297. <listitem>
  298. <para>
  299. <emphasis>adapterNamespace</emphasis>:
  300. początkowa część nazwy klasy używanego adaptera, używana zamiast
  301. '<classname>Zend_Db_Adapter</classname>'. Przydatna w przypadku użycia
  302. metody <methodname>factory()</methodname> do załadowana własnej klasy
  303. adaptera.
  304. </para>
  305. </listitem>
  306. </itemizedlist>
  307. <example id="zend.db.adapter.connecting.parameters.example1">
  308. <title>Przekazanie do fabryki opcji zmiany wielkości znaków</title>
  309. <para>
  310. Opcję tą można podać za pomocą stałej <constant>Zend_Db::CASE_FOLDING</constant>.
  311. Odpowiada ona atrybutowi <constant>ATTR_CASE</constant> w <acronym>PDO</acronym>
  312. oraz rozszerzeniu IBM DB2, który zmienia wielkość znaków w nazwach kolumn
  313. zwracanych w rezultacie zapytania. Opcja przybiera wartości
  314. <constant>Zend_Db::CASE_NATURAL</constant> (bez zmiany - domyślnie),
  315. <constant>Zend_Db::CASE_UPPER</constant> (zmiana na wielkie znaki) oraz
  316. <constant>Zend_Db::CASE_LOWER</constant> (zmiana na małe znaki).
  317. </para>
  318. <programlisting language="php"><![CDATA[
  319. $options = array(
  320. Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
  321. );
  322. $params = array(
  323. 'host' => '127.0.0.1',
  324. 'username' => 'webuser',
  325. 'password' => 'xxxxxxxx',
  326. 'dbname' => 'test',
  327. 'options' => $options
  328. );
  329. $db = Zend_Db::factory('Db2', $params);
  330. ]]></programlisting>
  331. </example>
  332. <example id="zend.db.adapter.connecting.parameters.example2">
  333. <title>Przekazanie do fabryki opcji automatycznego umieszczania w cudzysłowie</title>
  334. <para>
  335. Tą opcję można podać za pomocą stałej <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant>.
  336. Jeśli jej wartość wynosi <constant>TRUE</constant> (domyślnie) to identyfikatory
  337. takie jak nazwy tabel, kolumn oraz aliasy w składni każdego polecenia
  338. <acronym>SQL</acronym> generowanego za pomocą danego adaptera będą
  339. umieszczane w cudzysłowie. Takie podejście upraszcza używanie identyfikatorów
  340. zawierających słowa kluczowe <acronym>SQL</acronym> lub znaki specjalne. Jeśli
  341. wartość opcji wynosi <constant>FALSE</constant> to identyfikatory nie są
  342. umieszczane w cudzysłowie. Jeśli zachodzi potrzeba owinięcia identyfikatorów
  343. cudzysłowami należy to zrobić samodzielnie za pomocą metody
  344. <methodname>quoteIdentifier()</methodname>.
  345. </para>
  346. <programlisting language="php"><![CDATA[
  347. $options = array(
  348. Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
  349. );
  350. $params = array(
  351. 'host' => '127.0.0.1',
  352. 'username' => 'webuser',
  353. 'password' => 'xxxxxxxx',
  354. 'dbname' => 'test',
  355. 'options' => $options
  356. );
  357. $db = Zend_Db::factory('Pdo_Mysql', $params);
  358. ]]></programlisting>
  359. </example>
  360. <example id="zend.db.adapter.connecting.parameters.example3">
  361. <title>Przekazanie do fabryki opcji sterownika PDO</title>
  362. <programlisting language="php"><![CDATA[
  363. $pdoParams = array(
  364. PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
  365. );
  366. $params = array(
  367. 'host' => '127.0.0.1',
  368. 'username' => 'webuser',
  369. 'password' => 'xxxxxxxx',
  370. 'dbname' => 'test',
  371. 'driver_options' => $pdoParams
  372. );
  373. $db = Zend_Db::factory('Pdo_Mysql', $params);
  374. echo $db->getConnection()
  375. ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
  376. ]]></programlisting>
  377. </example>
  378. <example id="zend.db.adapter.connecting.parameters.example4">
  379. <title>Przekazanie do fabryki opcji serializacji</title>
  380. <programlisting language="php"><![CDATA[
  381. $options = array(
  382. Zend_Db::ALLOW_SERIALIZATION => false
  383. );
  384. $params = array(
  385. 'host' => '127.0.0.1',
  386. 'username' => 'webuser',
  387. 'password' => 'xxxxxxxx',
  388. 'dbname' => 'test',
  389. 'options' => $options
  390. );
  391. $db = Zend_Db::factory('Pdo_Mysql', $params);
  392. ]]></programlisting>
  393. </example>
  394. </sect3>
  395. <sect3 id="zend.db.adapter.connecting.getconnection">
  396. <title>Zarządzanie leniwymi połączeniami</title>
  397. <para>
  398. Utworzenie instancji klasy adaptera nie powoduje natychmiastowego połączenia
  399. z serwerem bazy danych. Adapter zachowuje parametry połączenia ale łączy się
  400. na żądanie - w momencie pierwszego wywołania zapytania. Dzięki temu zainicjowanie
  401. adaptera jest szybkie i tanie. Można utworzyć adapter nawet jeśli nie jest
  402. się pewnym czy wykonanie jakiegokolwiek zapytania przy danym połączeniu będzie
  403. niezbędne.
  404. </para>
  405. <para>
  406. Jeśli zajdzie potrzeba zmuszenia adaptera do połączenia z bazą danych, należy wówczas
  407. wywołać metodę <methodname>getConnection()</methodname>. Zwraca ona obiekt połączenia
  408. odpowiednio do rozszerzenia <acronym>PHP</acronym> używanego do połączenia. Jeśli
  409. używa się adaptera korzystającego z <acronym>PDO</acronym>, to metoda
  410. <methodname>getConnection()</methodname>, po zainicjowaniu połączenia z serwerem bazy
  411. danych, zwróci obiekt <acronym>PDO</acronym>.
  412. </para>
  413. <para>
  414. Możliwość wymuszenia połączenia z bazą danych może być przydatna gdy chce się
  415. złapać wyjątki rzucane przez adapter powstałe w rezultacie podania złych danych
  416. uwierzytelniających lub innych błędów połączenia. Te wyjątki nie są rzucane dopóki
  417. nie jest ustanowiona próba połączenia, więc można uprościć kod aplikacji i obsłużyć
  418. je w jednym miejscu. W przeciwnym razie należałoby je przechwycać w momencie
  419. wywołania pierwszego zapytania do bazy danych.
  420. </para>
  421. <para>
  422. Dodatkowo adapter może zostać poddany serializacji i przechowany np. w zmiennej sesyjnej.
  423. Może to być pomocne nie tylko dla adaptera ale również z punktu widzenia obiektów,
  424. które z niego korzystają, takich jak <classname>Zend_Db_Select</classname>. Domyślnie
  425. serializacja adapterów jest dozwolona ale jeśli jest taka potrzeba - można ją wyłączyć
  426. poprzez podanie opcji <constant>Zend_Db::ALLOW_SERIALIZATION</constant> z wartością
  427. <constant>FALSE</constant> (przykład niżej). Aby pozostać w zgodzie z zasadą leniwego
  428. połączenia, adapter nie połączy się automatycznie po odserializowaniu. Należy zatem
  429. wywołać metodę <methodname>getConnection()</methodname>. Można również zmusić adapter
  430. aby po odserializowaniu łączył się z bazą danych automatycznie poprzez podanie opcji
  431. <constant>Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE</constant> z wartością <constant>TRUE</constant>.
  432. </para>
  433. <example id="zend.db.adapter.connecting.getconnection.example">
  434. <title>Obsługa wyjątków połączenia</title>
  435. <programlisting language="php"><![CDATA[
  436. try {
  437. $db = Zend_Db::factory('Pdo_Mysql', $parameters);
  438. $db->getConnection();
  439. } catch (Zend_Db_Adapter_Exception $e) {
  440. // przyczyną problemów mogą być złe dane uwierzytelniające lub np. baza danych nie jest uruchomiona
  441. } catch (Zend_Exception $e) {
  442. // przyczyną może być np. problem z załadowaniem odpowiedniej klasy adaptera
  443. }
  444. ]]></programlisting>
  445. </example>
  446. </sect3>
  447. </sect2>
  448. <sect2 id="zend.db.adapter.example-database">
  449. <title>Przykładowa baza danych</title>
  450. <para>
  451. W dokumentacji klas <classname>Zend_Db</classname> używany jest prosty zestaw tabel w
  452. celu zilustrowania użycia klas i metod. Te tabele mogą przechowywać dane związane z
  453. przechowywaniem błędów (bugs) powstałych podczas rozwijania projektu informatycznego. Baza
  454. danych zawiera cztery tabele:
  455. </para>
  456. <itemizedlist>
  457. <listitem>
  458. <para>
  459. <emphasis>accounts</emphasis> przechowuje informacje o każdym użytkowniku
  460. bazy danych błędów.
  461. </para>
  462. </listitem>
  463. <listitem>
  464. <para>
  465. <emphasis>products</emphasis> przechowuje informacje o każdym produkcie,
  466. dla którego można zapisać wystąpienie usterki.
  467. </para>
  468. </listitem>
  469. <listitem>
  470. <para>
  471. <emphasis>bugs</emphasis> przechowuje informacje o błędach, włączając
  472. jego obecny stan, osobę zgłaszającą, osobę przypisaną do rozwiązania
  473. problemu oraz osobę przeznaczoną do zweryfikowania poprawności
  474. zastosowanego rozwiązania.
  475. </para>
  476. </listitem>
  477. <listitem>
  478. <para>
  479. <emphasis>bugs_products</emphasis> przechowuje relację pomiędzy usterkami
  480. a produktami. To odzwierciedla połączenie wiele-do-wielu, ponieważ dany błąd
  481. może się odnosić do wielu produktów a jeden produkt może posiadać wiele usterek.
  482. </para>
  483. </listitem>
  484. </itemizedlist>
  485. <para>
  486. Poniższy pseudokod definicji danych <acronym>SQL</acronym> opisuje tabele z tego przykładu.
  487. Te tabele są bardzo często używane w testach jednostkowych <classname>Zend_Db</classname>.
  488. </para>
  489. <programlisting language="sql"><![CDATA[
  490. CREATE TABLE accounts (
  491. account_name VARCHAR(100) NOT NULL PRIMARY KEY
  492. );
  493. CREATE TABLE products (
  494. product_id INTEGER NOT NULL PRIMARY KEY,
  495. product_name VARCHAR(100)
  496. );
  497. CREATE TABLE bugs (
  498. bug_id INTEGER NOT NULL PRIMARY KEY,
  499. bug_description VARCHAR(100),
  500. bug_status VARCHAR(20),
  501. reported_by VARCHAR(100) REFERENCES accounts(account_name),
  502. assigned_to VARCHAR(100) REFERENCES accounts(account_name),
  503. verified_by VARCHAR(100) REFERENCES accounts(account_name)
  504. );
  505. CREATE TABLE bugs_products (
  506. bug_id INTEGER NOT NULL REFERENCES bugs,
  507. product_id INTEGER NOT NULL REFERENCES products,
  508. PRIMARY KEY (bug_id, product_id)
  509. );
  510. ]]></programlisting>
  511. <para>
  512. Należy zwrócić uwagę, iż tabela 'bugs' zawiera wiele kluczy obcych
  513. odnoszących się do tabeli 'accounts'. Każdy z nich może prowadzić do
  514. innego wiersza tabeli 'accounts' w ramach jednego bugu.
  515. </para>
  516. <para>
  517. Poniższy diagram ilustruje fizyczny model danych przykładowej bazy danych
  518. </para>
  519. <para>
  520. <inlinegraphic width="387" scale="100" align="center" valign="middle"
  521. fileref="figures/zend.db.adapter.example-database.png" format="PNG" />
  522. </para>
  523. </sect2>
  524. <sect2 id="zend.db.adapter.select">
  525. <title>Pobranie rezultatów zapytania</title>
  526. <para>
  527. Ta część opisuje metody klasy adaptera za pomocą których można wywołać
  528. zapytania <acronym>SELECT</acronym> oraz pobrać ich rezultaty.
  529. </para>
  530. <sect3 id="zend.db.adapter.select.fetchall">
  531. <title>Pobranie całego zbioru rezultatów</title>
  532. <para>
  533. Za pomocą metody <methodname>fetchAll()</methodname> można wywołać zapytanie
  534. <acronym>SQL</acronym> <acronym>SELECT</acronym> oraz pobrać jego rezultaty
  535. w jednym kroku.
  536. </para>
  537. <para>
  538. Pierwszym argumentem metody jest łańcuch znaków zawierający polecenie
  539. <acronym>SELECT</acronym>. Alternatywnie, w pierwszym argumencie można umieścić
  540. obiekt klasy <link linkend="zend.db.select">Zend_Db_Select</link>. Adapter
  541. automatycznie dokonuje konwersji tego obiektu do łańcucha znaków zawierającego
  542. zapytanie <acronym>SELECT</acronym>.
  543. </para>
  544. <para>
  545. Drugi argument metody <methodname>fetchAll()</methodname> to tablica wartości
  546. używanych do zastąpienia parametrów wiązanych w zapytaniu <acronym>SQL</acronym>.
  547. </para>
  548. <example id="zend.db.adapter.select.fetchall.example">
  549. <title>Użycie metody fetchAll()</title>
  550. <programlisting language="php"><![CDATA[
  551. $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
  552. $result = $db->fetchAll($sql, 2);
  553. ]]></programlisting>
  554. </example>
  555. </sect3>
  556. <sect3 id="zend.db.adapter.select.fetch-mode">
  557. <title>Zmiana trybu zwracania danych</title>
  558. <para>
  559. Domyślnie <methodname>fetchAll()</methodname> zwraca tablicę wierszy, z których
  560. każdy jest tablicą asocjacyjną. Kluczami tablicy asocjacyjnej są kolumny lub ich
  561. aliasy podane w zapytaniu <acronym>SELECT</acronym>.
  562. </para>
  563. <para>
  564. Można ustawić inny tryb zwracania rezultatów poprzez metodę
  565. <methodname>setFetchMode()</methodname>. Dopuszczalne tryby są identyfikowane
  566. przez stałe:
  567. </para>
  568. <itemizedlist>
  569. <listitem>
  570. <para>
  571. <emphasis>Zend_Db::FETCH_ASSOC</emphasis>:
  572. zwraca dane w postaci tablicy tablic asocjacyjnych. Klucze tablicy asocjacyjnej
  573. to nazwy kolumn. To jest domyślny tryb zwrotu danych w klasach
  574. <classname>Zend_Db_Adapter</classname>.
  575. </para>
  576. <para>
  577. Należy zwrócić uwagę na fakt iż jeśli lista kolumn do zwrotu zawiera więcej niż
  578. jedną kolumnę o określonej nazwie, np. jeśli pochodzą one z różnych tabel
  579. połączonych klauzulą <acronym>JOIN</acronym>, to w asocjacyjnej tablicy wynikowej
  580. może być tylko jeden klucz o podanej nazwie. Jeśli używany jest tryb
  581. <acronym>FETCH_ASSOC</acronym>, należy upewnić się, że kolumny w zapytaniu
  582. <acronym>SELECT</acronym> posiadają aliasy, dzięki czemu rezultat zapytania
  583. będzie zawierał unikatowe nazwy kolumn.
  584. </para>
  585. <para>
  586. Domyślnie, łańcuchy znaków z nazwami kolumn są zwracane w taki sposób w jaki
  587. zostały otrzymane przez sterownik bazy danych. Przeważnie jest odpowiada to
  588. stylowi nazw kolumn używanego rodzaju bazy danych. Dzięki opcji
  589. <constant>Zend_Db::CASE_FOLDING</constant> można określić wielkość zwracanych
  590. znaków. Opcji tej można użyć podczas inicjowania adaptera. Przykład:
  591. <xref linkend="zend.db.adapter.connecting.parameters.example1" />.
  592. </para>
  593. </listitem>
  594. <listitem>
  595. <para>
  596. <emphasis>Zend_Db::FETCH_NUM</emphasis>:
  597. zwraca dane jako tablicę tablic. Indeksami tablicy są liczby całkowite
  598. odpowiadające pozycji danej kolumny w liście <acronym>SELECT</acronym>
  599. zapytania.
  600. </para>
  601. </listitem>
  602. <listitem>
  603. <para>
  604. <emphasis>Zend_Db::FETCH_BOTH</emphasis>:
  605. zwraca dane jako tablicę tablic. Kluczami tablicy są zarówno łańcuchy znaków
  606. (tak jak w trybie FETCH_ASSOC) oraz liczby całkowite (tak jak w trybie
  607. FETCH_NUM). Należy zwrócić uwagę na fakt iż liczba elementów tablicy wynikowej
  608. będzie dwukrotnie większa niż w przypadku użycia trybów FETCH_ASSOC
  609. lub FETCH_NUM.
  610. </para>
  611. </listitem>
  612. <listitem>
  613. <para>
  614. <emphasis>Zend_Db::FETCH_COLUMN</emphasis>:
  615. zwraca dane jako tablicę wartości. Wartości odpowiadają rezultatom zapytania
  616. przypisanym jednej kolumnie zbioru wynikowego. Domyślnie, jest to pierwsza kolumna,
  617. indeksy rozpoczynają się od 0.
  618. </para>
  619. </listitem>
  620. <listitem>
  621. <para>
  622. <emphasis>Zend_Db::FETCH_OBJ</emphasis>:
  623. zwraca dane jako tablicę obiektów. Domyślną klasą jest wbudowana w <acronym>PHP</acronym>
  624. klasa stdClass. Kolumny rezultatu zapytania stają się właściwościami powstałego obiektu.
  625. </para>
  626. </listitem>
  627. </itemizedlist>
  628. <example id="zend.db.adapter.select.fetch-mode.example">
  629. <title>Użycie metody setFetchMode()</title>
  630. <programlisting language="php"><![CDATA[
  631. $db->setFetchMode(Zend_Db::FETCH_OBJ);
  632. $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
  633. // $result jest tablicą obiektów
  634. echo $result[0]->bug_description;
  635. ]]></programlisting>
  636. </example>
  637. </sect3>
  638. <sect3 id="zend.db.adapter.select.fetchassoc">
  639. <title>Pobranie rezultatów jako tablicy asocjacyjnej</title>
  640. <para>
  641. Metoda <methodname>fetchAssoc()</methodname> zwraca dane w formie tablicy tablic
  642. asocjacyjnych, niezależnie od wartości ustalonej jako tryb zwracania rezultatów zapytania.
  643. </para>
  644. <example id="zend.db.adapter.select.fetchassoc.example">
  645. <title>Użycie fetchAssoc()</title>
  646. <programlisting language="php"><![CDATA[
  647. $db->setFetchMode(Zend_Db::FETCH_OBJ);
  648. $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
  649. // $result staje się tablicą tablic asocjacyjnych, mimo ustawionego trybu zwracania rezultatów zapytania
  650. echo $result[0]['bug_description'];
  651. ]]></programlisting>
  652. </example>
  653. </sect3>
  654. <sect3 id="zend.db.adapter.select.fetchcol">
  655. <title>Zwrócenie pojedynczej kolumny ze zbioru wynikowego</title>
  656. <para>
  657. Metoda <methodname>fetchCol()</methodname> zwraca dane w postaci tablicy wartości
  658. niezależnie od wartości ustalonej jako tryb zwrcania rezultatów zapytania. Ta
  659. metoda zwraca pierwszą kolumnę ze zbioru powstałego na skutek wywołania zapytania.
  660. Inne kolumny znajdujące się w tym zbiorze są ignorowane. Aby zwrócić inną niż
  661. pierwsza kolumnę należy skorzystać z przykładu
  662. <xref linkend="zend.db.statement.fetching.fetchcolumn" />.
  663. </para>
  664. <example id="zend.db.adapter.select.fetchcol.example">
  665. <title>Użycie fetchCol()</title>
  666. <programlisting language="php"><![CDATA[
  667. $db->setFetchMode(Zend_Db::FETCH_OBJ);
  668. $result = $db->fetchCol(
  669. 'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
  670. // zawiera bug_description; bug_id nie zostanie zwrócona
  671. echo $result[0];
  672. ]]></programlisting>
  673. </example>
  674. </sect3>
  675. <sect3 id="zend.db.adapter.select.fetchpairs">
  676. <title>Zwrócenie ze zbioru wynikowego par klucz-wartość</title>
  677. <para>
  678. Metoda <methodname>fetchPairs()</methodname> zwraca dane w postaci tablicy
  679. par klucz-wartość. Zwracana jest to tablica asocjacyjna z pojedynczą wartością
  680. w każdym polu. Wartości z pierwszej kolumny zapytania <acronym>SELECT</acronym>
  681. stają się kluczami tablicy wynikowej zaś wartości drugiej zostają umieszczone
  682. jako wartości tablicy. Pozostałe kolumny zwracane przez zapytanie są ignorowane.
  683. </para>
  684. <para>
  685. Należy konstruować zapytanie <acronym>SELECT</acronym> w taki sposób aby pierwsza
  686. kolumna posiadała unikalne wartości. W przeciwnym wypadku wartości tablicy asocjacyjnej
  687. zostaną nadpisane.
  688. </para>
  689. <example id="zend.db.adapter.select.fetchpairs.example">
  690. <title>Użycie fetchPairs()</title>
  691. <programlisting language="php"><![CDATA[
  692. $db->setFetchMode(Zend_Db::FETCH_OBJ);
  693. $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
  694. echo $result[2];
  695. ]]></programlisting>
  696. </example>
  697. </sect3>
  698. <sect3 id="zend.db.adapter.select.fetchrow">
  699. <title>Zwrócenie pojedynczego wiersza ze zbioru wynikowego</title>
  700. <para>
  701. Metoda <methodname>fetchRow()</methodname> pobiera dane używając bieżącego
  702. trybu zwracania rezultatów ale zwraca jedynie pierwszy wiersz ze zbioru
  703. wynikowego.
  704. </para>
  705. <example id="zend.db.adapter.select.fetchrow.example">
  706. <title>Using fetchRow()</title>
  707. <programlisting language="php"><![CDATA[
  708. $db->setFetchMode(Zend_Db::FETCH_OBJ);
  709. $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
  710. // $result to pojedynczy obiekt a nie tablica obiektów
  711. echo $result->bug_description;
  712. ]]></programlisting>
  713. </example>
  714. </sect3>
  715. <sect3 id="zend.db.adapter.select.fetchone">
  716. <title>Zwrócenie pojedynczej wartości ze zbioru wynikowego</title>
  717. <para>
  718. Metoda <methodname>fetchOne()</methodname> można opisać jako kombinacja
  719. <methodname>fetchRow()</methodname> oraz <methodname>fetchCol()</methodname>
  720. bo zwraca dane pochodzące z pierwszego wiersza zbioru wynikowego ograniczając
  721. kolumny do pierwszej w wierszu. Ostatecznie zostaje zwrócona pojedyncza
  722. wartość skalarna a nie tablica czy obiekt
  723. </para>
  724. <example id="zend.db.adapter.select.fetchone.example">
  725. <title>Using fetchOne()</title>
  726. <programlisting language="php"><![CDATA[
  727. $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
  728. // pojedyncza wartość string
  729. echo $result;
  730. ]]></programlisting>
  731. </example>
  732. </sect3>
  733. </sect2>
  734. <sect2 id="zend.db.adapter.write">
  735. <title>Zapisywanie zmian do bazy danych</title>
  736. <para>
  737. Adaptera klasy można użyć również do zapisania nowych, bądź do zmiany
  738. istniejących danych w bazie. Ta część opisuje metody włąściwe dla tych operacji.
  739. </para>
  740. <sect3 id="zend.db.adapter.write.insert">
  741. <title>Dodawanie danych</title>
  742. <para>
  743. Za pomocą metody <methodname>insert()</methodname> można dodać nowe wiersze
  744. do tabeli bazy danych. Jej pierwszym argumentem jest łańcuch znaków oznaczający
  745. nazwę tabeli. Drugim - tablica asocjacyjna z odwzorowaniem nazw kolumn i wartości
  746. jakie mają zostać w nich zapisane.
  747. </para>
  748. <example id="zend.db.adapter.write.insert.example">
  749. <title>Dodawanie danych do tabeli</title>
  750. <programlisting language="php"><![CDATA[
  751. $data = array(
  752. 'created_on' => '2007-03-22',
  753. 'bug_description' => 'Something wrong',
  754. 'bug_status' => 'NEW'
  755. );
  756. $db->insert('bugs', $data);
  757. ]]></programlisting>
  758. </example>
  759. <para>
  760. Kolumny, które nie zostały podane w tablicy z danymi nie będą umieszczone w zapytaniu.
  761. na zasadzie analogicznej do użycia polecenia <acronym>SQL</acronym> <acronym>INSERT</acronym>:
  762. Jeśli kolumna ma podaną wartość domyślną (<acronym>DEFAULT</acronym>) to ta wartość
  763. zostanie zapisana w nowym wierszu. W przeciwnym przypadku kolumna nie będzie miała żadnej
  764. wartości (<constant>NULL</constant>).
  765. </para>
  766. <para>
  767. Domyślnym sposobem zapisu danych jest użycie parametrów wiązanych. Dzięki temu ryzyko
  768. wystąpienia niektórych form zagrożenia bezpieczeństwa aplikacji jest ograniczone. W tablicy
  769. z danymi nie trzeba używać unikania lub umieszczania wartości w cudzysłowie.
  770. </para>
  771. <para>
  772. Może wystąpić potrzeba potraktowania wartości w tablicy danych jako wyrażeń
  773. <acronym>SQL</acronym>. W takim wypadku nie powinno się stosować umieszczania w cudzysłowie.
  774. Domyślnie wszystkie podane wartości string są traktowane jak literały. Aby upewnić się, że
  775. wartość jest wyrażeniem <acronym>SQL</acronym> i nie powinna zostać umieszczona w
  776. cudzysłowie, należy ją podać jako obiekt klasy <classname>Zend_Db_Expr</classname> zamiast
  777. prostego łańcucha znaków.
  778. </para>
  779. <example id="zend.db.adapter.write.insert.example2">
  780. <title>Umieszczanie wyrażeń w tabeli</title>
  781. <programlisting language="php"><![CDATA[
  782. $data = array(
  783. 'created_on' => new Zend_Db_Expr('CURDATE()'),
  784. 'bug_description' => 'Something wrong',
  785. 'bug_status' => 'NEW'
  786. );
  787. $db->insert('bugs', $data);
  788. ]]></programlisting>
  789. </example>
  790. </sect3>
  791. <sect3 id="zend.db.adapter.write.lastinsertid">
  792. <title>Pobranie wygenerowanej wartości</title>
  793. <para>
  794. Niektóre systemy zarządzania bazą danych wspierają klucze pierwotne o automatycznie
  795. zwiększanych wartościach. Tabela zdefiniowana w ten sposób generuje wartość klucza
  796. pierwotnego automatycznie przy każdym poleceniu <acronym>INSERT</acronym>. Wartością
  797. zwracaną przez metodę <methodname>insert()</methodname> <emphasis>nie</emphasis> jest
  798. ostatni zapisany identyfikator, ponieważ tabela mogła nie posiadać automatycznie
  799. inkrementowanej kolumny. Zamiast tego wartością zwrotną jest ilość zapisanych wierszy
  800. (przeważnie 1).
  801. </para>
  802. <para>
  803. Jeśli tabela jest zdefiniowana za pomocą automatycznego klucza pierwotnego to można
  804. użyć metody <methodname>lastInsertId()</methodname>. Po udanym dodaniu wiersza metoda
  805. ta zwraca ostatnią wartość klucza wygenerowaną w ramach bieżącego połączenia.
  806. </para>
  807. <example id="zend.db.adapter.write.lastinsertid.example-1">
  808. <title>Użycie lastInsertId() dla automatycznego klucza pierwotnego</title>
  809. <programlisting language="php"><![CDATA[
  810. $db->insert('bugs', $data);
  811. // zwrócenie ostatniej wartości wygenerowanej przez automatyczną kolumnę
  812. $id = $db->lastInsertId();
  813. ]]></programlisting>
  814. </example>
  815. <para>
  816. Niektóre systemy zarządzania bazą danych wspierają obiekt sekwencji, który służy
  817. do generowania unikalnych wartości, które mogą posłużyć jako klucz pierwotny.
  818. Aby obsługiwać również sekwencje metoda <methodname>lastInsertId()</methodname>
  819. akceptuje dodatkowe dwa argumenty. Pierwszym z nich jest nazwa tabeli zaś
  820. drugim - nazwa kolumny. Założona jest konwencja według której sekwencja ma nazwę
  821. składającą się z nazwy tabeli oraz kolumny do której generuje wartości z dodatkowym
  822. sufiksem "_seq". Podstawą tego założenia są domyślne ustawienia PostgreSQL. Przykładowo
  823. tabela "bugs" z kluczem pierwotnym w kolumnie "bug_id" będzie używała sekwencji o nazwie
  824. "bugs_bug_id_seq".
  825. </para>
  826. <example id="zend.db.adapter.write.lastinsertid.example-2">
  827. <title>Użycie lastInsertId() dla sekwencji</title>
  828. <programlisting language="php"><![CDATA[
  829. $db->insert('bugs', $data);
  830. // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_bug_id_seq'
  831. $id = $db->lastInsertId('bugs', 'bug_id');
  832. // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_seq'
  833. $id = $db->lastInsertId('bugs');
  834. ]]></programlisting>
  835. </example>
  836. <para>
  837. Jeśli nazwa obiektu sekwencji nie podąża za tą konwencją można użyć metody
  838. <methodname>lastSequenceId()</methodname>, która przyjmuje pojedynczy łańcuch
  839. znaków - nazwę sekwencji - jako argument.
  840. </para>
  841. <example id="zend.db.adapter.write.lastinsertid.example-3">
  842. <title>Użycie lastSequenceId()</title>
  843. <programlisting language="php"><![CDATA[
  844. $db->insert('bugs', $data);
  845. // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_id_gen'
  846. $id = $db->lastSequenceId('bugs_id_gen');
  847. ]]></programlisting>
  848. </example>
  849. <para>
  850. Dla systemów zarządzania bazą danych które nie wspierają sekwencji, włączając MySQL,
  851. Microsoft <acronym>SQL</acronym> Server, oraz SQLite dodatkowe argumenty podane do
  852. metody <methodname>lastInsertId()</methodname> są ignorowane a zwrócona jest
  853. ostatnia wartość wygenerowana dla dowolnej tabeli poprzez polecenie <acronym>INSERT</acronym>
  854. podczas bieżącego połączenia. Dla tych <acronym>RDBMS</acronym> metoda
  855. <methodname>lastSequenceId()</methodname> zawsze zwraca <constant>NULL</constant>.
  856. </para>
  857. <note>
  858. <title>Dlaczego nie należy używać "SELECT MAX(id) FROM table"?</title>
  859. <para>
  860. Powyższe zapytanie często zwraca ostatni klucz pierwotny, jaki został zapisany
  861. w wierszu tabeli. Ten sposób nie jest jednak bezpieczny w przypadku, gdy
  862. wiele klientów zapisuje rekordy do bazy danych. Jest możliwe, że w momencie
  863. pomiędzy zapisaniem jednego rekordu a zapytaniem o
  864. <methodname>MAX(id)</methodname>, do tabeli zostanie zapisany kolejny rekord,
  865. wprowadzony przez innego użytkownika. Przez to zwrócona wartość nie będzie
  866. identyfikowała pierwszego wprowadzonego wiersza tylko drugi - wprowadzony przez
  867. inne połączenie. Nie ma pewnego sposobu na wykrycie, że do takiego zdarzenia
  868. doszło.
  869. </para>
  870. <para>
  871. Zastosowanie mocnej izolacji transakcji, tak jak przy trybie "repeatable read" może
  872. pomóc w ograniczeniu ryzyka wystąpienia takiej sytuacji ale niektóre systemy
  873. zarządzania bazą danych nie wspierają izolacji transakcji w wystarczającym stopniu lub
  874. aplikacja może intencjonalnie korzystać jedynie z niskiego trybu izolacji transakcji.
  875. </para>
  876. <para>
  877. Dodatkowo, używanie wyrażeń takich jak "MAX(id)+1" do generowania nowych wartości
  878. klucza głównego nie jest bezpieczne bo dwa połączenia mogą wykonać to zapytanie
  879. praktycznie jednocześnie i w rezultacie próbować użyć jednakowej wartości
  880. dla kolejnego polecenia <acronym>INSERT</acronym>.
  881. </para>
  882. <para>
  883. Wszystkie systemy zarządzania bazą danych udostępniają mechanizmy służące generowaniu
  884. unikalnych wartości oraz zwracaniu ostatniej z nich. Mechanizmy te intencjonalnie
  885. działają poza zasięgiem izolacji transakcji więc nie jest możliwe aby wartość wygenerowana
  886. dla jednego klienta pojawiła się jako ostatnia wygenerowana dla innego połączenia.
  887. </para>
  888. </note>
  889. </sect3>
  890. <sect3 id="zend.db.adapter.write.update">
  891. <title>Aktualizacja danych</title>
  892. <para>
  893. Aktualizacji wierszy tabeli w bazie danych można dokonać poprzez metodę adaptera
  894. <methodname>update()</methodname> . Metoda przyjmuje trzy argumenty: pierwszym
  895. jest nazwa tabeli; drugim - tablica asocjacyjna mapująca kolumny, które mają ulec
  896. zmianie oraz wartości jakie kolumny przybiorą; trzecim - warunek wyznaczający wiersze
  897. do zmiany.
  898. </para>
  899. <para>
  900. Wartości w tablicy z danymi są traktowane jak literały znakowe. Należy zapoznać
  901. się z akapitem <xref linkend="zend.db.adapter.write.insert" /> aby uzyskać więcej
  902. informacji na temat użyci w niej wyrażeń <acronym>SQL</acronym>.
  903. </para>
  904. <para>
  905. Trzecim argumentem metody jest string zawierający wyrażenie <acronym>SQL</acronym>
  906. będące kryterium wyznaczającym wiersze do zmiany. Wartości i identyfikatory w tym
  907. argumencie nie są umieszczane w cudzysłowie ani unikane. Należy, więc, zadbać o to
  908. samemu. Należy zapoznać się z akapitem <xref linkend="zend.db.adapter.quoting" />
  909. aby zasięgnąć dodatkowych informacji.
  910. </para>
  911. <para>
  912. Wartością zwracaną jest ilość wierszy zmienionych przez operację aktualizacji.
  913. </para>
  914. <example id="zend.db.adapter.write.update.example">
  915. <title>Aktualizacja wierszy</title>
  916. <programlisting language="php"><![CDATA[
  917. $data = array(
  918. 'updated_on' => '2007-03-23',
  919. 'bug_status' => 'FIXED'
  920. );
  921. $n = $db->update('bugs', $data, 'bug_id = 2');
  922. ]]></programlisting>
  923. </example>
  924. <para>
  925. Jeśli trzeci argument nie zostanie podany to wszystkie wiersze w tabeli
  926. zostaną zaktualizowane zgodnie z kolumnami i wartościami podanymi w
  927. drugim argumencie.
  928. </para>
  929. <para>
  930. Jeśli trzeci argument zostanie podany jako tablica łańcuchów znakowych to
  931. w zapytaniu łańcuchy zostaną połączone za pomocą operatorów
  932. <constant>AND</constant>.
  933. </para>
  934. <para>
  935. Przy podaniu trzeciego argumentu jako tablicy tablic, ich wartości zostaną automatycznie
  936. otoczone cudzysłowami i umieszczone w kluczach tych tablic. Po czym zostaną
  937. połączone za pomocą operatorów <constant>AND</constant>.
  938. </para>
  939. <example id="zend.db.adapter.write.update.example-array">
  940. <title>Aktualizacja wierszy tablicy za pomocą tablicy wyrażeń</title>
  941. <programlisting language="php"><![CDATA[
  942. $data = array(
  943. 'updated_on' => '2007-03-23',
  944. 'bug_status' => 'FIXED'
  945. );
  946. $where[] = "reported_by = 'goofy'";
  947. $where[] = "bug_status = 'OPEN'";
  948. $n = $db->update('bugs', $data, $where);
  949. // Powstałe wyrażenie SQL to:
  950. // UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
  951. // WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
  952. ]]></programlisting>
  953. </example>
  954. <example id="zend.db.adapter.write.update.example-arrayofarrays">
  955. <title>Aktualizacja wierszy tablicy za pomocą tablicy tablic</title>
  956. <programlisting language="php"><![CDATA[
  957. $data = array(
  958. 'updated_on' => '2007-03-23',
  959. 'bug_status' => 'FIXED'
  960. );
  961. $where['reported_by = ?'] = 'goofy';
  962. $where['bug_status = ?'] = 'OPEN';
  963. $n = $db->update('bugs', $data, $where);
  964. // Powstałe wyrażenie SQL to:
  965. // UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
  966. // WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
  967. ]]></programlisting>
  968. </example>
  969. </sect3>
  970. <sect3 id="zend.db.adapter.write.delete">
  971. <title>Usuwanie danych</title>
  972. <para>
  973. Usuwania danych można dokonać używając metody <methodname>delete()</methodname>.
  974. Przyjmuje ona dwa argumenty: pierwszym z nich jest łańcuch znaków z nazwą tabeli;
  975. Drugim - warunek określający wiersze do usunięcia.
  976. </para>
  977. <para>
  978. Drugi argument to string zawierający wyrażenie <acronym>SQL</acronym> użyte jako
  979. kryterium wyznaczania usuwanych wierszy. Wartości i identyfikatory nie są
  980. unikane ani umieszczane w cudzysłowie - należy zatroszczyć się o to samemu. Aby
  981. dowiedzieć się więcej na ten temat
  982. można skorzystać z akapitu <xref linkend="zend.db.adapter.quoting" />.
  983. </para>
  984. <para>
  985. Wartość zwrotna to ilość wierszy, jakie uległy zmianie w wyniku zadziałania
  986. operacji usuwania.
  987. </para>
  988. <example id="zend.db.adapter.write.delete.example">
  989. <title>Usuwanie wierszy</title>
  990. <programlisting language="php"><![CDATA[
  991. $n = $db->delete('bugs', 'bug_id = 3');
  992. ]]></programlisting>
  993. </example>
  994. <para>
  995. Jeśli drugi argument nie zostanie podany to wszystkie wiersze z tabeli
  996. ulegną usunięciu.
  997. </para>
  998. <para>
  999. Jeśli drugi argument zostanie podany jako tablica łańcuchów znaków to
  1000. te łańcuchy ulegną konkatenacji jako wyrażenia logiczne połączone
  1001. operatorem <constant>AND</constant>.
  1002. </para>
  1003. <para>
  1004. Jeśli trzeci argument będzie tablicą tablic to jej wartości zostaną
  1005. automatycznie otoczone cudzysłowami i umieszczona w kluczach tablic. Potem
  1006. zostaną połączone razem za pomocą operatora <constant>AND</constant>.
  1007. </para>
  1008. </sect3>
  1009. </sect2>
  1010. <sect2 id="zend.db.adapter.quoting">
  1011. <title>Umieszczanie wartości i identyfikatorów w cudzysłowie</title>
  1012. <para>
  1013. Podczas tworzenia zapytań <acronym>SQL</acronym> często dochodzi do sytuacji, w której
  1014. niezbędne jest umieszczenie wartości zmiennych <acronym>PHP</acronym> w wyrażeniach
  1015. <acronym>SQL</acronym>. Stanowi to zagrożenie, ponieważ jeśli wartość
  1016. łańcuchowej zmiennej <acronym>PHP</acronym> zawiera określone znaki, takie jak symbol
  1017. cudzysłowu, to mogą one spowodować błąd w poleceniu <acronym>SQL</acronym>. Poniżej
  1018. znajduje się przykład zapytania zawierającego niespójną liczbę symboli cudzysłowu:
  1019. <programlisting language="php"><![CDATA[
  1020. $name = "O'Reilly";
  1021. $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
  1022. echo $sql;
  1023. // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
  1024. ]]></programlisting>
  1025. </para>
  1026. <para>
  1027. Zagrożenie potęguje fakt iż podobne błędy mogą zostać wykorzystane przez osobę
  1028. próbującą zmanipulować działanie funkcji aplikacji. Jeśli takiej osobie uda się wpłynąć na
  1029. wartość zmiennej <acronym>PHP</acronym> poprzez parametr <acronym>HTTP</acronym>
  1030. (bądź inny mechanizm), to będzie mogła zmienić zapytanie <acronym>SQL</acronym>
  1031. tak by dokonywało operacji zupełnie niezamierzonych przez twórców, takich jak
  1032. zwrócenie danych, do których osoba nie powinna mieć dostępu. To jest poważny i szeroko
  1033. rozpowszechniony sposób łamania zabezpieczeń aplikacji znany pod nazwą "SQL Injection"
  1034. (wstrzyknięcie SQL -
  1035. <ulink url="http://en.wikipedia.org/wiki/SQL_Injection">http://en.wikipedia.org/wiki/SQL_Injection</ulink>).
  1036. </para>
  1037. <para>
  1038. Adaptery klasy <classname>Zend_Db</classname> udostępniają funkcje przydatne do zredukowania
  1039. zagrożenia atakiem <acronym>SQL</acronym> Injection w kodzie <acronym>PHP</acronym>. Przyjętym
  1040. rozwiązaniem jest unikanie znaków specjalnych takich jak cudzysłów w
  1041. wartościach zmiennych <acronym>PHP</acronym>
  1042. przed umieszczeniem ich w poleceniu <acronym>SQL</acronym>. Takie podejście zapewnia ochronę
  1043. przed przypadkową jak i intencjonalną zmianą znaczenia poleceń <acronym>SQL</acronym> przez
  1044. zmienne <acronym>PHP</acronym> zawierające znaki specjalne.
  1045. </para>
  1046. <sect3 id="zend.db.adapter.quoting.quote">
  1047. <title>Użycie quote()</title>
  1048. <para>
  1049. Metoda <methodname>quote()</methodname> przyjmuje pojedynczy argument - łańcuch znaków.
  1050. Na wyjściu zwraca podany argument ze wszystkimi znakami specjalnymi poddanymi uniknięciu
  1051. w sposób właściwy dla używanego <acronym>RDBMS</acronym> i otoczony znakami ograniczającymi
  1052. łańcuchy znakowe. Standardowym znakiem ograniczającym stringi w <acronym>SQL</acronym>
  1053. jest pojedynczy cudzysłów (').
  1054. </para>
  1055. <example id="zend.db.adapter.quoting.quote.example">
  1056. <title>Użycie quote()</title>
  1057. <programlisting language="php"><![CDATA[
  1058. $name = $db->quote("O'Reilly");
  1059. echo $name;
  1060. // 'O\'Reilly'
  1061. $sql = "SELECT * FROM bugs WHERE reported_by = $name";
  1062. echo $sql;
  1063. // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
  1064. ]]></programlisting>
  1065. </example>
  1066. <para>
  1067. Należy zwrócić uwagę, że wartość zwrotna metody <methodname>quote()</methodname>
  1068. zawiera znaki ograniczające stringi. Jest to zachowanie różne od niektórych funkcji
  1069. które unikają specjalne znaki ale nie ujmują całego łańcucha w znaki ograniczające,
  1070. tak jak <ulink
  1071. url="http://www.php.net/mysqli_real_escape_string">mysql_real_escape_string()</ulink>.
  1072. </para>
  1073. <para>
  1074. Wartości mogą wymagać umieszczenia w cudzysłowach lub nie, zgodnie z kontekstem używanego
  1075. typu danych <acronym>SQL</acronym>. W przypadku niektórych rodzajów systemów zarządzania
  1076. bazą danych liczby całkowite nie mogą być ograniczane cudzysłowami jeśli są porównywane
  1077. z kolumną lub wyrażeniem zwracającym inną liczbę całkowitą. Innymi słowy, poniższy zapis
  1078. może wywołać błąd w niektórych implementacjach <acronym>SQL</acronym> zakładając, że
  1079. <property>intColumn</property> jest określona typem danych <constant>INTEGER</constant>.
  1080. <programlisting language="php"><![CDATA[
  1081. SELECT * FROM atable WHERE intColumn = '123'
  1082. ]]></programlisting>
  1083. </para>
  1084. <para>
  1085. Można użyć opcjonalnego, drugiego argumentu metody <methodname>quote()</methodname>
  1086. aby określić typ danych <acronym>SQL</acronym> i ograniczyć stosowanie cudzysłowu.
  1087. </para>
  1088. <example id="zend.db.adapter.quoting.quote.example-2">
  1089. <title>Użycie quote() z podanym typem danych SQL</title>
  1090. <programlisting language="php"><![CDATA[
  1091. $value = '1234';
  1092. $sql = 'SELECT * FROM atable WHERE intColumn = '
  1093. . $db->quote($value, 'INTEGER');
  1094. ]]></programlisting>
  1095. </example>
  1096. <para>
  1097. Każda klasa <classname>Zend_Db_Adapter</classname> ma zapisane nazwy numerycznych
  1098. typów danych <acronym>SQL</acronym> odpowiednio do swojego rodzaju <acronym>RDBMS</acronym>.
  1099. Zamiast tego można w tym miejscu również korzystać ze stałych
  1100. <constant>Zend_Db::INT_TYPE</constant>, <constant>Zend_Db::BIGINT_TYPE</constant> oraz
  1101. <constant>Zend_Db::FLOAT_TYPE</constant> aby uniezależnić kod od rodzaju bazy danych.
  1102. </para>
  1103. <para>
  1104. <classname>Zend_Db_Table</classname> automatycznie określa typy danych <acronym>SQL</acronym>
  1105. dla metody <methodname>quote()</methodname> podczas generowania zapytań <acronym>SQL</acronym>
  1106. odnoszących się do klucza pierwotnego tabeli.
  1107. </para>
  1108. </sect3>
  1109. <sect3 id="zend.db.adapter.quoting.quote-into">
  1110. <title>Użycie quoteInto()</title>
  1111. <para>
  1112. Najbardziej typowym przypadkiem użycia cudzysłowu do ograniczania zmiennych jest
  1113. umieszczenie zmiennej <acronym>PHP</acronym> w zapytaniu <acronym>SQL</acronym>. Aby
  1114. to osiągnąć można użyć metody <methodname>quoteInto()</methodname>. Przyjmuje ona
  1115. dwa argumenty: pierwszym jest łańcuch znaków zawierający symbol "?", który zostanie
  1116. zastąpiony; drugim jest zmienna <acronym>PHP</acronym>, która ma trafić na miejsce "?".
  1117. </para>
  1118. <para>
  1119. Zastępowany symbol jest używany przez wielu producentów baz danych do oznaczenia
  1120. pozycyjnych parametrów wiązanych ale metoda <methodname>quoteInto()</methodname>
  1121. jedynie emuluje takie parametry. W wyniku jej działania wartość zmiennej jest
  1122. zwyczajnie umieszczana w łańcuchu z zapytaniem, po wstępnym uniknięciu specjalnych
  1123. znaków i umieszczeniu w cudzysłowie. Prawdziwa implementacja parametrów wiązanych
  1124. zakłada separację łańcucha znaków polecenia <acronym>SQL</acronym> od samych
  1125. parametrów oraz wstępne parsowanie polecenia na serwerze bazy danych.
  1126. </para>
  1127. <example id="zend.db.adapter.quoting.quote-into.example">
  1128. <title>Użycie quoteInto()</title>
  1129. <programlisting language="php"><![CDATA[
  1130. $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
  1131. echo $sql;
  1132. // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
  1133. ]]></programlisting>
  1134. </example>
  1135. <para>
  1136. Można użyć opcjonalnego, trzeciego parametru metody <methodname>quoteInto()</methodname>
  1137. aby określić typ danych <acronym>SQL</acronym>. Numeryczne typy danych (w przeciwieństwie
  1138. do innych typów) nie podlegają umieszczaniu w cudzysłowie.
  1139. </para>
  1140. <example id="zend.db.adapter.quoting.quote-into.example-2">
  1141. <title>Użycie quoteInto() z podaniem typu danych SQL</title>
  1142. <programlisting language="php"><![CDATA[
  1143. $sql = $db
  1144. ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
  1145. echo $sql;
  1146. // SELECT * FROM bugs WHERE reported_by = 1234
  1147. ]]></programlisting>
  1148. </example>
  1149. </sect3>
  1150. <sect3 id="zend.db.adapter.quoting.quote-identifier">
  1151. <title>Użycie quoteIdentifier()</title>
  1152. <para>
  1153. Wartości nie są jedyną częścią składni polecenia <acronym>SQL</acronym>, która może
  1154. być zmienna. W przypadku użycia zmiennych <acronym>PHP</acronym> do określenia
  1155. tabel, kolumn lub innych identyfikatorów zapytania <acronym>SQL</acronym>, może zajść
  1156. potrzeba umieszczenia również tych elementów w cudzysłowie. Domyślnie identyfikatory
  1157. <acronym>SQL</acronym> muszą przestrzegać określonych reguł - podobnie jak w
  1158. <acronym>PHP</acronym> oraz większości innych języków programowania. Przykładem takiej
  1159. reguły jest zakaz używania spacji lub określonych znaków interpunkcyjnych, specjalnych
  1160. ani też znaków spoza ASCII. Poza tym istnieje lista określonych słów, które służą
  1161. do tworzenia zapytań - ich też nie powinno się używać jako identyfikatorów.
  1162. </para>
  1163. <para>
  1164. Mimo to <acronym>SQL</acronym> posiada <emphasis>ograniczone identyfikatory</emphasis>
  1165. (delimited identifiers), dzięki którym można skorzystać z większego wachlarza znaków
  1166. do nazywania obiektów. Jeśli określony identyfikator zostanie ograniczony odpowiednim
  1167. rodzajem cudzysłowu to będzie można użyć znaków, które bez tego ograniczenia
  1168. spowodowałyby błąd. Identyfikatory ograniczone mogą zawierać spacje, znaki interpunkcyjne
  1169. czy lokalne litery. Można nawet używać zarezerwowanych słów <acronym>SQL</acronym> jeśli
  1170. zostaną otoczone odpowiednimi znakami ograniczającymi.
  1171. </para>
  1172. <para>
  1173. Metoda <methodname>quoteIdentifier()</methodname> zachowuje się podobnie jak
  1174. <methodname>quote()</methodname> ale otacza podany łańcuch znaków za pomocą
  1175. znaków ograniczających zgodnie z rodzajem używanego adaptera. Standardowy <acronym>SQL</acronym>
  1176. używa podwójnego cudzysłowu (") jako znaku ograniczającego a większość systemów
  1177. zarządzania bazą danych podąża za tym przykładem. MySQL domyślnie używa znaków
  1178. back-tick (`). Metoda <methodname>quoteIdentifier()</methodname> dokonuje również
  1179. unikania znaków specjalnych znajdujących się w przekazanym argumencie.
  1180. </para>
  1181. <example id="zend.db.adapter.quoting.quote-identifier.example">
  1182. <title>Użycie quoteIdentifier()</title>
  1183. <programlisting language="php"><![CDATA[
  1184. // można użyć tabeli o nazwie takiej samej jak słowo zarezerwowane SQL
  1185. $tableName = $db->quoteIdentifier("order");
  1186. $sql = "SELECT * FROM $tableName";
  1187. echo $sql
  1188. // SELECT * FROM "order"
  1189. ]]></programlisting>
  1190. </example>
  1191. <para>
  1192. W <acronym>SQL</acronym> identyfikatory ograniczone są wrażliwe na wielkość liter,
  1193. w przeciwieństwie do zwykłych identyfikatorów. Przez to, należy upewnić się, że
  1194. pisownia identyfikatora w 100% odpowiada pisowni zapisanej w schemacie, włącznie
  1195. z wielkością liter.
  1196. </para>
  1197. <para>
  1198. W większości przypadków gdzie polecenie <acronym>SQL</acronym> jest generowane wewnątrz
  1199. klas <classname>Zend_Db</classname>, domyślnym zachowaniem jest automatyczne ograniczanie
  1200. identyfikatorów. Można to zmienić poprzez opcję
  1201. <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> wywoływaną podczas inicjalizacji
  1202. adaptera. Więcej informacji: <xref linkend="zend.db.adapter.connecting.parameters.example2" />.
  1203. </para>
  1204. </sect3>
  1205. </sect2>
  1206. <sect2 id="zend.db.adapter.transactions">
  1207. <title>Kontrolowanie transakcji bazy danych</title>
  1208. <para>
  1209. W świecie baz danych transakcja to zbiór operacji, który może zostać zapisany
  1210. bądź cofnięty za pomocą jednej instrukcji, nawet jeśli zmiany wynikające z tych operacji
  1211. dotyczyły wielu tabel. Wszystkie zapytania do bazy danych są przeprowadzane w
  1212. kontekście transakcji. Jeśli nie są zarządzane jawnie to sterownik bazy danych używa ich
  1213. w sposób przezroczysty dla użytkownika. Takie podejście nazywa się trybem
  1214. <emphasis>auto-commit</emphasis> - sterownik bazy danych tworzy transakcje dla każdego
  1215. tworzonego polecenia i zapisuje efekty jego działania po każdym wywołaniu polecenia
  1216. <acronym>SQL</acronym>. Domyślnie wszystkie adaptery <classname>Zend_Db</classname>
  1217. działają w trybie <emphasis>auto-commit</emphasis>.
  1218. </para>
  1219. <para>
  1220. Można również bezpośrednio wskazać początek i koniec transakcji i w ten sposób
  1221. kontrolować ilość zapytań <acronym>SQL</acronym> jakie trafiają do zapisania (bądź
  1222. cofnięcia) jako pojedyncza operacja. Aby rozpocząć transakcję należy wywołać metodę
  1223. <methodname>beginTransaction()</methodname>. Następujące po niej polecenia
  1224. <acronym>SQL</acronym> są wykonywane w kontekście wspólnej transakcji do momentu
  1225. zasygnalizowania jej końca.
  1226. </para>
  1227. <para>
  1228. Aby zakończyć transakcję należy użyć metody <methodname>commit()</methodname> lub
  1229. <methodname>rollBack()</methodname>. Pierwsza z nich powoduje zapisanie zmian wynikających
  1230. z operacji przeprowadzonych w czasie transakcji. Oznacza to, że efekty tych zmian będą
  1231. widoczne w wynikach zapytań wywołanych w ramach innych transakcji.
  1232. </para>
  1233. <para>
  1234. Metoda <methodname>rollBack()</methodname> dokonuje odwrotnej operacji: cofa zmiany
  1235. dokonane podczas transakcji. W efekcie wszystkie dane zmienione podczas transakcji zostają
  1236. cofnięte do wartości z momentu przed jej rozpoczęciem. Cofnięcie zmian jednej transakcji nie
  1237. ma wpływu na zmiany dokonane przez inną transakcję trwającą nawet w tym samym czasie.
  1238. </para>
  1239. <para>
  1240. Po skończonej transakcji <classname>Zend_Db_Adapter</classname> wraca do trybu auto-commit
  1241. do momentu ponownego wywołania metody <methodname>beginTransaction()</methodname> i ręcznego
  1242. rozpoczęcia nowej transakcji.
  1243. </para>
  1244. <example id="zend.db.adapter.transactions.example">
  1245. <title>Kontrolowanie transakcjami dla zachowania spójności</title>
  1246. <programlisting language="php"><![CDATA[
  1247. // Ręczne rozpoczęcie transakcji
  1248. $db->beginTransaction();
  1249. try {
  1250. // Próba wywołania jednego bądź wielu zapytań:
  1251. $db->query(...);
  1252. $db->query(...);
  1253. $db->query(...);
  1254. // Jeśli wszystkie odniosły sukces - zapisanie transakcji, dzięki czemu wszystkie rezultaty
  1255. // zostaną zapisane za jednym razem.
  1256. $db->commit();
  1257. } catch (Exception $e) {
  1258. // Jeśli któreś z zapytań zakończyło się niepowodzeniem i został wyrzucony wyjątek, należy
  1259. // cofnąć całą transakcję odwracając zmiany w niej dokonane (nawet te które zakończyły się
  1260. // sukcesem). Przez to albo wszystkie zmiany zostają zapisane albo żadna.
  1261. $db->rollBack();
  1262. echo $e->getMessage();
  1263. }
  1264. ]]></programlisting>
  1265. </example>
  1266. </sect2>
  1267. <sect2 id="zend.db.adapter.list-describe">
  1268. <title>Uzyskiwanie listy i opisu tabel</title>
  1269. <para>
  1270. Metoda <methodname>listTables()</methodname> zwraca tablicę łańcuchów znakowych,
  1271. zawierającą wszystkie tabele w bieżącej bazie danych.
  1272. </para>
  1273. <para>
  1274. Metoda <methodname>describeTable()</methodname> zwraca tablicę asocjacyjną metadanych
  1275. tabeli. Jako argument należy podać nazwę tabeli. Drugi argument jest opcjonalny - wskazuje
  1276. nazwę schematu w którym tabela się znajduje.
  1277. </para>
  1278. <para>
  1279. Kluczami zwracanej tablicy asocjacyjnej są nazwy kolumn tabeli. Wartość przy każdej
  1280. kolumnie to następna tablica asocjacyjna z następującymi kluczami i wartościami:
  1281. </para>
  1282. <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
  1283. <title>Metadane zwracane przez describeTable()</title>
  1284. <tgroup cols="3" align="left" colsep="1" rowsep="1">
  1285. <thead>
  1286. <row>
  1287. <entry>Klucz</entry>
  1288. <entry>Typ</entry>
  1289. <entry>Opis</entry>
  1290. </row>
  1291. </thead>
  1292. <tbody>
  1293. <row>
  1294. <entry><constant>SCHEMA_NAME</constant></entry>
  1295. <entry>(string)</entry>
  1296. <entry>Nazwa schematu bazy danych, w którym tabela się znajduje.</entry>
  1297. </row>
  1298. <row>
  1299. <entry><constant>TABLE_NAME</constant></entry>
  1300. <entry>(string)</entry>
  1301. <entry>Nazwa tabeli zawierającej daną kolumnę.</entry>
  1302. </row>
  1303. <row>
  1304. <entry><constant>COLUMN_NAME</constant></entry>
  1305. <entry>(string)</entry>
  1306. <entry>Nazwa kolumny.</entry>
  1307. </row>
  1308. <row>
  1309. <entry><constant>COLUMN_POSITION</constant></entry>
  1310. <entry>(integer)</entry>
  1311. <entry>Liczba porządkowa wskazująca na miejsce kolumny w tabeli.</entry>
  1312. </row>
  1313. <row>
  1314. <entry><constant>DATA_TYPE</constant></entry>
  1315. <entry>(string)</entry>
  1316. <entry>Nazwa typu danych dozwolonych w kolumnie.</entry>
  1317. </row>
  1318. <row>
  1319. <entry><constant>DEFAULT</constant></entry>
  1320. <entry>(string)</entry>
  1321. <entry>Domyślna wartość kolumny (jeśli istnieje).</entry>
  1322. </row>
  1323. <row>
  1324. <entry><constant>NULLABLE</constant></entry>
  1325. <entry>(boolean)</entry>
  1326. <entry>
  1327. <constant>TRUE</constant> jeśli columna dopuszcza wartości <acronym>SQL</acronym>
  1328. <constant>NULL</constant>, <constant>FALSE</constant> jeśli kolumna zawiera
  1329. ograniczenie <constant>NOT</constant> <constant>NULL</constant>.
  1330. </entry>
  1331. </row>
  1332. <row>
  1333. <entry><constant>LENGTH</constant></entry>
  1334. <entry>(integer)</entry>
  1335. <entry>
  1336. Dopuszczalny rozmiar kolumny, w formie zgłoszonej przez serwer bazy danych.
  1337. </entry>
  1338. </row>
  1339. <row>
  1340. <entry><constant>SCALE</constant></entry>
  1341. <entry>(integer)</entry>
  1342. <entry>
  1343. Skala typów <acronym>SQL</acronym> NUMERIC lub <constant>DECIMAL</constant>.
  1344. </entry>
  1345. </row>
  1346. <row>
  1347. <entry><constant>PRECISION</constant></entry>
  1348. <entry>(integer)</entry>
  1349. <entry>
  1350. Precyzja typów <acronym>SQL</acronym> NUMERIC lub <constant>DECIMAL</constant>.
  1351. </entry>
  1352. </row>
  1353. <row>
  1354. <entry><constant>UNSIGNED</constant></entry>
  1355. <entry>(boolean)</entry>
  1356. <entry>
  1357. <constant>TRUE</constant> jeśli typ danych liczbowych ma klauzulę
  1358. <constant>UNSIGNED</constant>.
  1359. </entry>
  1360. </row>
  1361. <row>
  1362. <entry><constant>PRIMARY</constant></entry>
  1363. <entry>(boolean)</entry>
  1364. <entry>
  1365. <constant>TRUE</constant> jeśli kolumna jest częścią klucza pierwotnego tabeli.
  1366. </entry>
  1367. </row>
  1368. <row>
  1369. <entry><constant>PRIMARY_POSITION</constant></entry>
  1370. <entry>(integer)</entry>
  1371. <entry>
  1372. Liczba porządkowa (min. 1) oznaczająca pozycję kolumny w kluczu pierwotnym.
  1373. </entry>
  1374. </row>
  1375. <row>
  1376. <entry><constant>IDENTITY</constant></entry>
  1377. <entry>(boolean)</entry>
  1378. <entry>
  1379. <constant>TRUE</constant> jeśli kolumna korzysta z wartości automatycznie generowanych.
  1380. </entry>
  1381. </row>
  1382. </tbody>
  1383. </tgroup>
  1384. </table>
  1385. <note>
  1386. <title>Pole metadanych IDENTITY w różnych systemach zarządzania bazą danych</title>
  1387. <para>
  1388. Pole metadanych IDENTITY zostało wybrane jako ogólny
  1389. termin określający relację do klucza tabeli. Może być znany pod następującymi nazwami:
  1390. </para>
  1391. <itemizedlist>
  1392. <listitem>
  1393. <para>
  1394. <constant>IDENTITY</constant> - DB2, MSSQL
  1395. </para>
  1396. </listitem>
  1397. <listitem>
  1398. <para>
  1399. <constant>AUTO_INCREMENT</constant> - MySQL
  1400. </para>
  1401. </listitem>
  1402. <listitem>
  1403. <para>
  1404. <constant>SERIAL</constant> - PostgreSQL
  1405. </para>
  1406. </listitem>
  1407. <listitem>
  1408. <para>
  1409. <constant>SEQUENCE</constant> - Oracle
  1410. </para>
  1411. </listitem>
  1412. </itemizedlist>
  1413. </note>
  1414. <para>
  1415. Jeśli w bazie danych nie istnieje tabela i schemat o podanych nazwach to
  1416. <methodname>describeTable()</methodname> zwraca pustą tablicę.
  1417. </para>
  1418. </sect2>
  1419. <sect2 id="zend.db.adapter.closing">
  1420. <title>Zamykanie połączenia</title>
  1421. <para>
  1422. Najczęściej nie ma potrzeby zamykać połączenia z bazą danych. <acronym>PHP</acronym>
  1423. automatycznie czyści wszystkie zasoby pod koniec działania. Rozszerzenia bazy danych są
  1424. zaprojektowane w taki sposób aby połączenie zostało zamknięte w momencie usunięcia
  1425. referencji do obiektu zasobu.
  1426. </para>
  1427. <para>
  1428. Jednak w przypadku skryptu <acronym>PHP</acronym>, którego czas wykonania jest znaczący,
  1429. który inicjuje wiele połączeń z bazą danych, może zajść potrzeba ręcznego zamknięcia połączenia
  1430. aby ograniczyć wykorzystanie zasobów serwera bazy danych. Aby wymusić zamknięcie połączenia
  1431. z bazą danych należy użyć metody adaptera <methodname>closeConnection()</methodname>.
  1432. </para>
  1433. <para>
  1434. Od wersji 1.7.2 istnieje możliwość sprawdzenia czy w obecnej chwili połączenie z serwerem
  1435. bazy danych występuje za pomocą metody <methodname>isConnected()</methodname>. Jej rezultat
  1436. oznacza czy zasób połączenia został ustanowiony i nie został zamknięty. Ta metoda nie jest
  1437. zdolna sprawdzić zamknięcia połączenia od strony serwera bazy danych. Dzięki użyciu jej
  1438. w wewnętrznych metodach zamykających połączenie można dokonywać wielokrotnego zamknięcia
  1439. połączenia bez ryzyka wystąpienia błędów. Przed wersją 1.7.2 było to możliwe jedynie w
  1440. przypadku adapterów <acronym>PDO</acronym>.
  1441. </para>
  1442. <example id="zend.db.adapter.closing.example">
  1443. <title>Zamknięcie połączenia z bazą danych</title>
  1444. <programlisting language="php"><![CDATA[
  1445. $db->closeConnection();
  1446. ]]></programlisting>
  1447. </example>
  1448. <note>
  1449. <title>Czy Zend_Db wspiera stałe połączenia (Persistent Connections)?</title>
  1450. <para>
  1451. Tak, trwałe połączenia są wspierane poprzez flagę <property>persistent</property>
  1452. ustawioną na wartość <constant>TRUE</constant> w konfiguracji
  1453. adaptera <classname>Zend_Db</classname> (a nie sterownika bazy danych).
  1454. </para>
  1455. <example id="zend.db.adapter.connecting.persistence.example">
  1456. <title>Użycie flagi stałego połączenia z adapterem Oracle</title>
  1457. <programlisting language="php"><![CDATA[
  1458. $db = Zend_Db::factory('Oracle', array(
  1459. 'host' => '127.0.0.1',
  1460. 'username' => 'webuser',
  1461. 'password' => 'xxxxxxxx',
  1462. 'dbname' => 'test',
  1463. 'persistent' => true
  1464. ));
  1465. ]]></programlisting>
  1466. </example>
  1467. <para>
  1468. Należy zwrócić uwagę, że używanie połączeń stałych może zwiększyć ilość
  1469. nieużywanych połączeń na serwerze bazy danych. Przez to, korzyści
  1470. w wydajności (wynikające z wykluczenia potrzeby nawiązywania połączenia
  1471. przy każdym żądaniu) mogą zostać skutecznie przeważone przez problemy
  1472. spowodowane przez tą technikę.
  1473. </para>
  1474. <para>
  1475. Połączenia z bazą danych mają stany. Oznacza to, że pewne obiekty na serwerze
  1476. bazy danych istnieją w kontekście sesji. Chodzi o blokady, zmienne użytkownika,
  1477. tabele tymczasowe, informacje o ostatnio wykonanym zapytaniu - takie jak
  1478. ilość pobranych wierszy, ostatnia wygenerowana wartość identyfikatora. W
  1479. przypadku użycia połączeń stałych istnieje ryzyko, że aplikacja uzyska
  1480. dostęp do niepoprawnych bądź zastrzeżonych danych, które zostały utworzone
  1481. podczas poprzedniego żądania.
  1482. </para>
  1483. <para>
  1484. W obecnym stanie jedynie adaptery Oracle, DB2 oraz <acronym>PDO</acronym>
  1485. (zgodnie z dokumentacją <acronym>PHP</acronym>) wspierają połączenia stałe
  1486. w <classname>Zend_Db</classname>.
  1487. </para>
  1488. </note>
  1489. </sect2>
  1490. <sect2 id="zend.db.adapter.other-statements">
  1491. <title>Wykonywanie innych poleceń na bazie danych</title>
  1492. <para>
  1493. Podczas tworzenia kodu może zajść potrzeba uzyskania dostępu bezpośrednio do
  1494. obiektu połączenia tak jak udostępnia to używane rozszerzenie bazy danych
  1495. <acronym>PHP</acronym>. Niektóre rozszerzenia mogą oferować funkcje nieodzwierciedlone
  1496. w metodach klasy <classname>Zend_Db_Adapter_Abstract</classname>.
  1497. </para>
  1498. <para>
  1499. Wszystkie polecenia <acronym>SQL</acronym> w <classname>Zend_Db</classname>
  1500. są wywoływane poprzez instrukcje preparowane (prepared statement). Jednak niektóre
  1501. funkcje bazy danych są z nimi niekompatybilne. Polecenia <acronym>DDL</acronym> takie
  1502. jak CREATE czy ALTER nie mogą być wywoływane w ten sposób w MySQL. Dodatkowo polecenia
  1503. <acronym>SQL</acronym> nie korzystają z
  1504. <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">cache'u zapytań
  1505. MySQL (MySQL Query Cache)</ulink> dla wersji wcześniejszej niż MySQL 5.1.17.
  1506. </para>
  1507. <para>
  1508. Większość rozszerzeń baz danych <acronym>PHP</acronym> umożliwia wywoływanie poleceń
  1509. <acronym>SQL</acronym> bez preparowania. W przypadku <acronym>PDO</acronym> jest to
  1510. możliwe poprzez metodę <methodname>exec()</methodname>. Aby uzyskać dostęp do obiektu
  1511. połączenia odpowiedniego rozszerzenia <acronym>PHP</acronym> należy wywołać metodę
  1512. <methodname>getConnection()</methodname>.
  1513. </para>
  1514. <example id="zend.db.adapter.other-statements.example">
  1515. <title>Wywołanie polecenia niepreparowanego dla adaptera PDO</title>
  1516. <programlisting language="php"><![CDATA[
  1517. $result = $db->getConnection()->exec('DROP TABLE bugs');
  1518. ]]></programlisting>
  1519. </example>
  1520. <para>
  1521. W podobny sposób można korzystać z innych metod szczególnych dla konkretnego
  1522. rozszerzenia <acronym>PHP</acronym>. Należy jednak mieć w pamięci, iż w ten
  1523. sposób ogranicza się tworzoną aplikację do współpracy z interfejsem oferowanym
  1524. jedynie przez konkretne rozszerzenie konkretnej bazy danych.
  1525. </para>
  1526. <para>
  1527. W przyszłych wersjach <classname>Zend_Db</classname> planowane jest umieszczanie
  1528. dodatkowych metod służących do obejmowania funkcjonalności wspólnych dla wielu
  1529. rozszerzeń baz danych <acronym>PHP</acronym> ale wsteczna kompatybilność zostanie
  1530. zachowana.
  1531. </para>
  1532. </sect2>
  1533. <sect2 id="zend.db.adapter.server-version">
  1534. <title>Pobranie wersji serwera</title>
  1535. <para>
  1536. Począwszy od wersji 1.7.2 można pobrać wersję serwera bazy danych w formie podobnej do
  1537. numeru wersji <acronym>PHP</acronym> tak aby można było skorzystać z funkcji
  1538. <methodname>version_compare()</methodname>. Jeśli taka informacja nie jest dostępna
  1539. to zostanie zwrócona wartość <constant>NULL</constant>.
  1540. </para>
  1541. <example id="zend.db.adapter.server-version.example">
  1542. <title>Weryfikacja wersji serwera przed wywołaniem zapytania</title>
  1543. <programlisting language="php"><![CDATA[
  1544. $version = $db->getServerVersion();
  1545. if (!is_null($version)) {
  1546. if (version_compare($version, '5.0.0', '>=')) {
  1547. // wykonanie zapytania
  1548. } else {
  1549. // wykonanie innego zapytania
  1550. }
  1551. } else {
  1552. // wersja serwera niedostępna
  1553. }
  1554. ]]></programlisting>
  1555. </example>
  1556. </sect2>
  1557. <sect2 id="zend.db.adapter.adapter-notes">
  1558. <title>Informacje o konkretnych adapterach</title>
  1559. <para>
  1560. Ten akapit wymienia różnice pomiędzy klasami adapterów, z istnienia których
  1561. należy sobie zdawać sprawę.
  1562. </para>
  1563. <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
  1564. <title>IBM DB2</title>
  1565. <itemizedlist>
  1566. <listitem>
  1567. <para>
  1568. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1569. należy użyć nazwy 'Db2'.
  1570. </para>
  1571. </listitem>
  1572. <listitem>
  1573. <para>
  1574. Ten adapter używa rozszerzenia <acronym>PHP</acronym> ibm_db2.
  1575. </para>
  1576. </listitem>
  1577. <listitem>
  1578. <para>
  1579. IBM DB2 wspiera sekwencje oraz klucze automatycznie zwiększające.
  1580. Przez to argumenty dla <methodname>lastInsertId()</methodname> są
  1581. opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
  1582. wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
  1583. podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
  1584. o nazwie zgodnej z konwencją
  1585. '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'.
  1586. </para>
  1587. </listitem>
  1588. </itemizedlist>
  1589. </sect3>
  1590. <sect3 id="zend.db.adapter.adapter-notes.mysqli">
  1591. <title>MySQLi</title>
  1592. <itemizedlist>
  1593. <listitem>
  1594. <para>
  1595. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1596. należy użyć nazwy 'Mysqli'.
  1597. </para>
  1598. </listitem>
  1599. <listitem>
  1600. <para>
  1601. Ten adapter używa rozszerzenia <acronym>PHP</acronym> mysqli.
  1602. </para>
  1603. </listitem>
  1604. <listitem>
  1605. <para>
  1606. MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
  1607. ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
  1608. automatycznego. Metoda <methodname>lastSequenceId()</methodname>
  1609. zwraca <constant>NULL</constant>.
  1610. </para>
  1611. </listitem>
  1612. </itemizedlist>
  1613. </sect3>
  1614. <sect3 id="zend.db.adapter.adapter-notes.oracle">
  1615. <title>Oracle</title>
  1616. <itemizedlist>
  1617. <listitem>
  1618. <para>
  1619. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1620. należy użyć nazwy 'Oracle'.
  1621. </para>
  1622. </listitem>
  1623. <listitem>
  1624. <para>
  1625. Ten adapter używa rozszerzenia <acronym>PHP</acronym> oci8.
  1626. </para>
  1627. </listitem>
  1628. <listitem>
  1629. <para>
  1630. Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
  1631. sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
  1632. <methodname>lastSequenceId()</methodname>.
  1633. </para>
  1634. </listitem>
  1635. <listitem>
  1636. <para>
  1637. Rozszerzenie Oracle nie wspiera parametrów pozycyjnych. Należy
  1638. używać nazwanych parametrów.
  1639. </para>
  1640. </listitem>
  1641. <listitem>
  1642. <para>
  1643. Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
  1644. zaimplementowana w tym adapterze. Aby użyć tej opcji z Oracle zalecane
  1645. jest korzystanie z adaptera <acronym>PDO</acronym> OCI.
  1646. </para>
  1647. </listitem>
  1648. <listitem>
  1649. <para>
  1650. Domyślnie pola LOB są zwracane jako obiekty OCI-Lob. Można ustawić
  1651. pobieranie ich w formie łańcuchów znakowych dla wszystkich żądań
  1652. poprzez opcję sterownika '<property>lob_as_string</property>'. Aby
  1653. jednorazowo pobrać obiekt Lob jako string należy użyć metody
  1654. <methodname>setLobAsString(boolean)</methodname> na adapterze lub
  1655. na obiekcie zapytania.
  1656. </para>
  1657. </listitem>
  1658. </itemizedlist>
  1659. </sect3>
  1660. <sect3 id="zend.db.adapter.adapter-notes.sqlsrv">
  1661. <title>Microsoft SQL Server</title>
  1662. <itemizedlist>
  1663. <listitem>
  1664. <para>
  1665. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1666. należy użyć nazwy 'Sqlsrv'.
  1667. </para>
  1668. </listitem>
  1669. <listitem>
  1670. <para>
  1671. Ten adapter używa rozszerzenia <acronym>PHP</acronym> sqlsrv.
  1672. </para>
  1673. </listitem>
  1674. <listitem>
  1675. <para>
  1676. Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
  1677. <methodname>lastInsertId()</methodname> ignoruje argument określający
  1678. klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
  1679. klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
  1680. ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname>
  1681. zwraca <constant>NULL</constant>.
  1682. </para>
  1683. </listitem>
  1684. <listitem>
  1685. <para>
  1686. <classname>Zend_Db_Adapter_Sqlsrv</classname> ustawia opcję
  1687. <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
  1688. z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
  1689. zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
  1690. ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu
  1691. Microsoftu - nawiasów kwadratowych.
  1692. </para>
  1693. </listitem>
  1694. <listitem>
  1695. <para>
  1696. Jednym z kluczy podawanych do tablicy opcji może być <property>driver_options</property>
  1697. dzięki czemu można skorzystać z wartości podanych w dokumentacji <acronym>SQL</acronym> Server
  1698. <ulink url="http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx">
  1699. http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx</ulink>.
  1700. </para>
  1701. </listitem>
  1702. <listitem>
  1703. <para>
  1704. Dzięki metodzie <methodname>setTransactionIsolationLevel()</methodname> można
  1705. ustawić poziom izolacji transakcji dla bieżącego połączenia. Rozpoznawane wartości
  1706. to <constant>SQLSRV_TXN_READ_UNCOMMITTED</constant>,
  1707. <constant>SQLSRV_TXN_READ_COMMITTED</constant>,
  1708. <constant>SQLSRV_TXN_REPEATABLE_READ</constant>,
  1709. <constant>SQLSRV_TXN_SNAPSHOT</constant> or
  1710. <constant>SQLSRV_TXN_SERIALIZABLE</constant>.
  1711. </para>
  1712. </listitem>
  1713. <listitem>
  1714. <para>
  1715. Począwszy od Zend Framework 1.9 minimalną wspieraną wersją rozszerzenia
  1716. <acronym>PHP</acronym> Microsoft <acronym>SQL</acronym> Server jest
  1717. 1.0.1924.0. a dla <acronym>MSSQL</acronym> Server Native
  1718. Client - wersja 9.00.3042.00.
  1719. </para>
  1720. </listitem>
  1721. </itemizedlist>
  1722. </sect3>
  1723. <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
  1724. <title>PDO dla IBM DB2 oraz Informix Dynamic Server (IDS)</title>
  1725. <itemizedlist>
  1726. <listitem>
  1727. <para>
  1728. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1729. należy użyć nazwy '<classname>Pdo_Ibm</classname>'.
  1730. </para>
  1731. </listitem>
  1732. <listitem>
  1733. <para>
  1734. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_ibm.
  1735. </para>
  1736. </listitem>
  1737. <listitem>
  1738. <para>
  1739. Należy używać wersji 1.2.2 lub wyższej rozszerzenia PDO_IBM. Zaleca się
  1740. uaktualnienie wcześniejszych wersji poprzez <acronym>PECL</acronym>.
  1741. </para>
  1742. </listitem>
  1743. </itemizedlist>
  1744. </sect3>
  1745. <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
  1746. <title>PDO Microsoft SQL Server</title>
  1747. <itemizedlist>
  1748. <listitem>
  1749. <para>
  1750. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1751. należy użyć nazwy '<classname>Pdo_Mssql</classname>'.
  1752. </para>
  1753. </listitem>
  1754. <listitem>
  1755. <para>
  1756. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_dblib.
  1757. </para>
  1758. </listitem>
  1759. <listitem>
  1760. <para>
  1761. Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
  1762. <methodname>lastInsertId()</methodname> ignoruje argument określający
  1763. klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
  1764. klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
  1765. ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname>
  1766. zwraca <constant>NULL</constant>.
  1767. </para>
  1768. </listitem>
  1769. <listitem>
  1770. <para>
  1771. W przypadku pracy z łańcuchami znaków unicode zakodowanych w sposób inny
  1772. niż UCS-2 (czyli również w formie UTF-8), może zajść potrzeba dokonania
  1773. konwersji w kodzie aplikacji lub przechowywania danych w kolumnach binarnych.
  1774. Aby uzyskać więcej informacji można skorzystać z
  1775. <ulink url="http://support.microsoft.com/kb/232580">Microsoft's Knowledge
  1776. Base</ulink>.
  1777. </para>
  1778. </listitem>
  1779. <listitem>
  1780. <para>
  1781. <classname>Zend_Db_Adapter_Pdo_Mssql</classname> ustawia opcję
  1782. <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
  1783. z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
  1784. zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
  1785. ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu
  1786. Microsoftu - nawiasów kwadratowych.
  1787. </para>
  1788. </listitem>
  1789. <listitem>
  1790. <para>
  1791. Adapter rozpoznaje klucz <property>pdoType</property> w tablicy opcji. Jego
  1792. wartość może wynosić "mssql" (domyślnie), "dblib", "freetds", lub "sybase".
  1793. To wpływa na prefiks <acronym>DSN</acronym> używany przez adapter do utworzenia
  1794. łańcucha połączenia. "freetds" oraz "sybase" powodują utworzenie prefiksu
  1795. "sybase:" używanego przez biblioteki
  1796. <ulink url="http://www.freetds.org/">FreeTDS</ulink>.
  1797. Należy zapoznać się z informacjami dotyczącymi prefiksów <acronym>DSN</acronym>
  1798. używanymi przez ten sterownik pod adresem
  1799. <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
  1800. http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>
  1801. </para>
  1802. </listitem>
  1803. </itemizedlist>
  1804. </sect3>
  1805. <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
  1806. <title>PDO MySQL</title>
  1807. <itemizedlist>
  1808. <listitem>
  1809. <para>
  1810. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1811. należy użyć nazwy '<classname>Pdo_Mysql</classname>'.
  1812. </para>
  1813. </listitem>
  1814. <listitem>
  1815. <para>
  1816. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_mysql.
  1817. </para>
  1818. </listitem>
  1819. <listitem>
  1820. <para>
  1821. MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
  1822. ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
  1823. automatycznego. Metoda <methodname>lastSequenceId()</methodname>
  1824. zwraca <constant>NULL</constant>.
  1825. </para>
  1826. </listitem>
  1827. </itemizedlist>
  1828. </sect3>
  1829. <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
  1830. <title>PDO Oracle</title>
  1831. <itemizedlist>
  1832. <listitem>
  1833. <para>
  1834. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1835. należy użyć nazwy '<classname>Pdo_Oci</classname>'.
  1836. </para>
  1837. </listitem>
  1838. <listitem>
  1839. <para>
  1840. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_oci.
  1841. </para>
  1842. </listitem>
  1843. <listitem>
  1844. <para>
  1845. Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
  1846. sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
  1847. <methodname>lastSequenceId()</methodname>.
  1848. </para>
  1849. </listitem>
  1850. </itemizedlist>
  1851. </sect3>
  1852. <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
  1853. <title>PDO PostgreSQL</title>
  1854. <itemizedlist>
  1855. <listitem>
  1856. <para>
  1857. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1858. należy użyć nazwy '<classname>Pdo_Pgsql</classname>'.
  1859. </para>
  1860. </listitem>
  1861. <listitem>
  1862. <para>
  1863. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_pgsql.
  1864. </para>
  1865. </listitem>
  1866. <listitem>
  1867. <para>
  1868. PostgreSQL wspiera sekwencje oraz klucze automatyczne. Przez to
  1869. podawanie argumentów w <methodname>lastInsertId()</methodname> jest
  1870. opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
  1871. wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
  1872. podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
  1873. o nazwie zgodnej z konwencją
  1874. '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'.
  1875. </para>
  1876. </listitem>
  1877. </itemizedlist>
  1878. </sect3>
  1879. <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
  1880. <title>PDO SQLite</title>
  1881. <itemizedlist>
  1882. <listitem>
  1883. <para>
  1884. Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
  1885. należy użyć nazwy '<classname>Pdo_Sqlite</classname>'.
  1886. </para>
  1887. </listitem>
  1888. <listitem>
  1889. <para>
  1890. Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_sqlite.
  1891. </para>
  1892. </listitem>
  1893. <listitem>
  1894. <para>
  1895. SQLite nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
  1896. ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
  1897. automatycznego. Metoda <methodname>lastSequenceId()</methodname>
  1898. zwraca <constant>NULL</constant>.
  1899. </para>
  1900. </listitem>
  1901. <listitem>
  1902. <para>
  1903. Aby połączyć się z bazą danych SQLite2 należy podać
  1904. <command>'sqlite2' => true</command> jako jeden z elementów
  1905. tablicy parametrów podczas tworzenia instancji adaptera
  1906. <classname>Pdo_Sqlite</classname>.
  1907. </para>
  1908. </listitem>
  1909. <listitem>
  1910. <para>
  1911. Aby połączyć się z bazą danych SQLite rezydującą w pamięci
  1912. należy podać <command>'dbname' => ':memory:'</command> jako
  1913. jeden z elementów tablicy parametrów podczas tworzenia instancji adaptera
  1914. <classname>Pdo_Sqlite</classname>.
  1915. </para>
  1916. </listitem>
  1917. <listitem>
  1918. <para>
  1919. Starsze wersje sterownika <acronym>PHP</acronym> SQLite nie wspierają
  1920. poleceń PRAGMA niezbędnych dla zachowania krótkich nazw kolumn w
  1921. wynikach zapytania. W przypadku wystąpienia problemów z zapytaniami JOIN
  1922. polegających na zwracaniu wyników z nazwami kolumn w postaci
  1923. "tabela.kolumna" zaleca się aktualizację <acronym>PHP</acronym> do
  1924. najnowszej wersji.
  1925. </para>
  1926. </listitem>
  1927. </itemizedlist>
  1928. </sect3>
  1929. <sect3 id="zend.db.adapter.adapter-notes.firebird">
  1930. <title>Firebird/Interbase</title>
  1931. <itemizedlist>
  1932. <listitem>
  1933. <para>
  1934. Ten adapter używa rozszerzenia <acronym>PHP</acronym> php_interbase.
  1935. </para>
  1936. </listitem>
  1937. <listitem>
  1938. <para>
  1939. Firebird/Interbase nie wspiera kluczy automatycznych więc należy podać nazwę
  1940. sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
  1941. <methodname>lastSequenceId()</methodname>.
  1942. </para>
  1943. </listitem>
  1944. <listitem>
  1945. <para>
  1946. Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
  1947. zaimplementowana w tym adapterze. Identyfikatory bez znaków ograniczających
  1948. są zwracane w postaci wielkich liter.
  1949. </para>
  1950. </listitem>
  1951. <listitem>
  1952. <para>
  1953. Nazwa adaptera to <classname>ZendX_Db_Adapter_Firebird</classname>.
  1954. </para>
  1955. <para>
  1956. Należy pamiętać o użyciu parametru adapterNamespace z wartością
  1957. <classname>ZendX_Db_Adapter</classname>.
  1958. </para>
  1959. <para>
  1960. Zaleca się aktualizację pliku <filename>gds32.dll</filename> (lub
  1961. odpowiednika wersji linux) dostarczanym z php do wersji odpowiadającej
  1962. serwerowi bazy danych. Dla Firebird odpowiednikiem
  1963. <filename>gds32.dll</filename> jest
  1964. <filename>fbclient.dll</filename>.
  1965. </para>
  1966. <para>
  1967. Domyślnie wszystkie identyfikatory (nazwy tabel, kolumn) są zwracane
  1968. wielkimi literami.
  1969. </para>
  1970. </listitem>
  1971. </itemizedlist>
  1972. </sect3>
  1973. </sect2>
  1974. </sect1>
  1975. <!--
  1976. vim:se ts=4 sw=4 et:
  1977. -->