| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 21740 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.db.adapter">
- <title>Zend_Db_Adapter</title>
- <para>
- <classname>Zend_Db</classname> i powiązane z nim klasy udostępniają prosty interfejs
- dla baz danych <acronym>SQL</acronym> z poziomu Zend Framework. Klasa
- <classname>Zend_Db_Adapter</classname> jest podstawowym komponentem potrzebnym by
- połączyć aplikację PHP z systemem zarządzania bazą danych (<acronym>RDBMS</acronym>).
- Dla każdego rodzaju bazy danych istnieje oddzielna klasa adaptera
- <classname>Zend_Db</classname>.
- </para>
- <para>
- Adaptery <classname>Zend_Db</classname> tworzą połączenie pomiędzy rozszerzeniami
- <acronym>PHP</acronym> dla konkretnych rodzajów baz danych a wspólnym interfejsem,
- dzięki czemu można napisać aplikację raz i w nieskomplikowany sposób uruchamiać
- ją z wieloma rodzajami <acronym>RDBMS</acronym>
- </para>
- <para>
- Interfejs klasy adaptera jest podobny do interfejsu rozszerzenia
- <ulink url="http://www.php.net/pdo">PHP Data Objects</ulink>. <classname>Zend_Db</classname>
- zawiera klasy adapterów dla sterowników <acronym>PDO</acronym> następujących rodzajów
- baz danych:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- IBM DB2 oraz Informix Dynamic Server (IDS), poprzez rozszerzenie
- <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>.
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-mysql">pdo_mysql</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Microsoft <acronym>SQL</acronym> Server, używając rozszerzenia
- <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-dblib">pdo_dblib</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- PostgreSQL, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-pgsql">pdo_pgsql</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- SQLite, używając rozszerzenia <acronym>PHP</acronym>
- <ulink url="http://www.php.net/pdo-sqlite">pdo_sqlite</ulink>
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Dodatkowo <classname>Zend_Db</classname> dostarcza klas adapterów korzystających
- z rozszerzeń <acronym>PHP</acronym> dla następujących rodzajów
- baz danych:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/mysqli">mysqli</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/oci8">oci8</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- IBM DB2 oraz DB2/i5, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
- </para>
- </listitem>
- <listitem>
- <para>
- Firebird/Interbase, poprzez rozszerzenie <acronym>PHP</acronym>
- <ulink url="http://www.php.net/ibase">php_interbase</ulink>
- </para>
- </listitem>
- </itemizedlist>
- <note>
- <para>
- Każdy adapter <classname>Zend_Db</classname> używa określonego rozszerzenia
- <acronym>PHP</acronym>. Aby użyć adaptera należy mieć zainstalowane i włączone
- odpowiadające mu rozszerzenie <acronym>PHP</acronym>. Np. aby użyć dowolnego
- adaptera <acronym>PDO</acronym> <classname>Zend_Db</classname>, wymagane jest
- posiadanie włączonego rozszerzenia <acronym>PDO</acronym> oraz sterownika dla
- danego rodzaju <acronym>RDBMS</acronym>.
- </para>
- </note>
- <sect2 id="zend.db.adapter.connecting">
- <title>Połączenie z bazą danych za pomocą adaptera</title>
- <para>
- Ta część opisuje jak tworzy się instancję adaptera bazy danych. Jest to odpowiednik
- połączenia z bazą danych w aplikacji <acronym>PHP</acronym>.
- </para>
- <sect3 id="zend.db.adapter.connecting.constructor">
- <title>Użycie konstruktora adaptera Zend_Db</title>
- <para>
- Można utworzyć instancję adaptera za pomocą konstruktora. Przyjmuje on
- pojedynczy argument - tablicę parametrów używanych do deklaracji połączenia.
- </para>
- <example id="zend.db.adapter.connecting.constructor.example">
- <title>Użycie konstruktora adaptera</title>
- <programlisting language="php"><![CDATA[
- $db = new Zend_Db_Adapter_Pdo_Mysql(array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test'
- ));
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.factory">
- <title>Użycie fabryki Zend_Db</title>
- <para>
- Alternatywą w stosunku do bezpośredniego używania konstruktora jest utworzenie
- instancji adaptera za pomocą statycznej metody
- <methodname>Zend_Db::factory()</methodname>. Ta metoda dynamicznie ładuje plik
- klasy adaptera używając
- <link linkend="zend.loader.load.class">Zend_Loader::loadClass()</link>.
- </para>
- <para>
- Pierwszy argument metody to łańcuch znaków, który wyznacza nazwę bazową klasy
- adaptera. Np. string '<classname>Pdo_Mysql</classname>' odpowiada klasie
- <classname>Zend_Db_Adapter_Pdo_Mysql</classname>. Drugi argument to ta sama
- tablica parametrów, którą należało podać adapterowi konstruktora.
- </para>
- <example id="zend.db.adapter.connecting.factory.example">
- <title>Użycie metody fabryki adaptera</title>
- <programlisting language="php"><![CDATA[
- // Poniższa instrukcja jest zbędna ponieważ plik z klasą
- // Zend_Db_Adapter_Pdo_Mysql zostanie załadowany przez fabrykę
- // Zend_Db
- // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
- // Załaduj klasę Zend_Db_Adapter_Pdo_Mysql automatycznie
- // i utwórz jej instancję
- $db = Zend_Db::factory('Pdo_Mysql', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test'
- ));
- ]]></programlisting>
- </example>
- <para>
- Jeśli jest zdefiniowana własna klasa dziedzicząca po
- <classname>Zend_Db_Adapter_Abstract</classname> ale jej nazwa nie zawiera
- "<classname>Zend_Db_Adapter</classname>", można użyć metody
- <methodname>factory()</methodname> do załadowania adaptera jedynie jeśli
- poda się swój prefiks nazwy adaptera z kluczem 'adapterNamespace' do
- argumentu zawierającego parametry połączenia.
- </para>
- <example id="zend.db.adapter.connecting.factory.example2">
- <title>Użycie metody fabryki dla własnej klasy adaptera</title>
- <programlisting language="php"><![CDATA[
- // Nie trzeba ładować pliku klasy adaptera
- // bo robi to metoda fabryki Zend_Db
- // Załadowanie klasy MyProject_Db_Adapter_Pdo_Mysql automatycznie
- // i utworzenie jej instancji
- $db = Zend_Db::factory('Pdo_Mysql', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'adapterNamespace' => 'MyProject_Db_Adapter'
- ));
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.factory-config">
- <title>Użycie Zend_Config z fabryką Zend_Db</title>
- <para>
- Każdy z argumentów metody <methodname>factory()</methodname> może również zostać
- podany w formie obiektu klasy <link linkend="zend.config">Zend_Config</link>.
- </para>
- <para>
- Jeśli pierwszy argument jest obiektem <classname>Zend_Config</classname>
- to wymagane jest aby posiadał właściwość o nazwie
- <property>adapter</property>, w której będzie zapisany łańcuch znaków
- określający nazwę bazową klasy adaptera. Opcjonalnie, obiekt ten może zawierać
- właściwość '<property>params</property>' z właściwościami potomnymi
- odpowiadającymi nazwom parametrów adaptera. Będą one użyte jedynie w
- przypadku braku drugiego argumentu metody
- <methodname>factory()</methodname>.
- </para>
- <example id="zend.db.adapter.connecting.factory.example1">
- <title>Użycie metody fabryki adaptera z obiektem Zend_Config</title>
- <para>
- W poniższym przykładzie, obiekt <classname>Zend_Config</classname>
- jest utworzony z tablicy.
- Można również załadować dane z pliku zewnętrznego poprzez klasy
- <link linkend="zend.config.adapters.ini">Zend_Config_Ini</link> oraz
- <link linkend="zend.config.adapters.xml">Zend_Config_Xml</link>.
- </para>
- <programlisting language="php"><![CDATA[
- $config = new Zend_Config(
- array(
- 'database' => array(
- 'adapter' => 'Mysqli',
- 'params' => array(
- 'host' => '127.0.0.1',
- 'dbname' => 'test',
- 'username' => 'webuser',
- 'password' => 'secret',
- )
- )
- )
- );
- $db = Zend_Db::factory($config->database);
- ]]></programlisting>
- </example>
- <para>
- Drugi argument metody <methodname>factory()</methodname> może stanowić tablicę
- asocjacyjną zawierającą wartości odpowiadające parametrom adaptera. Ten argument
- jest opcjonalny. Jeśli pierwszy argument jest obiektem klasy
- <classname>Zend_Config</classname> to powinien zawierać wszystkie parametry a
- drugi argument jest ignorowany.
- </para>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.parameters">
- <title>Parametry adaptera</title>
- <para>
- Poniższa lista opisuje parametry wspólne dla klas adapterów
- <classname>Zend_Db</classname>.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>host</emphasis>:
- łańcuch znaków zawierający nazwę hosta lub adres IP serwera bazy danych.
- Jeśli baza danych jest uruchomiona na tej samej maszynie co aplikacja to
- można tu umieścić 'localhost' lub '127.0.0.1'.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>username</emphasis>:
- identyfikator użytkownika używany do autoryzacji połączenia z serwerem
- bazy danych.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>password</emphasis>:
- hasło użytkownika używane do autoryzacji połączenia z serwerem
- bazy danych.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>dbname</emphasis>:
- nazwa instancji bazy danych na serwerze.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>port</emphasis>:
- niektóre serwery bazy danych używają do komunikacji numeru portu określonego
- przez administratora. Ten parametr pozwala na ustawienie numeru portu przez
- który aplikacja <acronym>PHP</acronym> się łączy tak aby zgadzał się z tym
- ustawionym na serwerze bazy danych.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>charset</emphasis>:
- określenie zestawu znaków używanego podczas połączenia.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>options</emphasis>:
- ten parametr to tablica asocjacyjna opcji obsługiwanych przez wszystkie
- klasy <classname>Zend_Db_Adapter</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>driver_options</emphasis>:
- ten parametr to tablica asocjacyjna zawierająca dodatkowe opcje
- specyficzne dla każdego rozszerzenia bazy danych. Typowym przykładem
- użycia tego parametru jest zbiór atrybutów sterownika
- <acronym>PDO</acronym>.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>adapterNamespace</emphasis>:
- początkowa część nazwy klasy używanego adaptera, używana zamiast
- '<classname>Zend_Db_Adapter</classname>'. Przydatna w przypadku użycia
- metody <methodname>factory()</methodname> do załadowana własnej klasy
- adaptera.
- </para>
- </listitem>
- </itemizedlist>
- <example id="zend.db.adapter.connecting.parameters.example1">
- <title>Przekazanie do fabryki opcji zmiany wielkości znaków</title>
- <para>
- Opcję tą można podać za pomocą stałej
- <constant>Zend_Db::CASE_FOLDING</constant>.
- Odpowiada ona atrybutowi <constant>ATTR_CASE</constant> w <acronym>PDO</acronym>
- oraz rozszerzeniu IBM DB2, który zmienia wielkość znaków w nazwach kolumn
- zwracanych w rezultacie zapytania. Opcja przybiera wartości
- <constant>Zend_Db::CASE_NATURAL</constant> (bez zmiany - domyślnie),
- <constant>Zend_Db::CASE_UPPER</constant> (zmiana na wielkie znaki) oraz
- <constant>Zend_Db::CASE_LOWER</constant> (zmiana na małe znaki).
- </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Db2', $params);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example2">
- <title>Przekazanie do fabryki opcji automatycznego umieszczania
- w cudzysłowie</title>
- <para>
- Tą opcję można podać za pomocą stałej
- <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant>.
- Jeśli jej wartość wynosi <constant>TRUE</constant> (domyślnie) to identyfikatory
- takie jak nazwy tabel, kolumn oraz aliasy w składni każdego polecenia
- <acronym>SQL</acronym> generowanego za pomocą danego adaptera będą
- umieszczane w cudzysłowie. Takie podejście upraszcza używanie identyfikatorów
- zawierających słowa kluczowe <acronym>SQL</acronym> lub znaki specjalne. Jeśli
- wartość opcji wynosi <constant>FALSE</constant> to identyfikatory nie są
- umieszczane w cudzysłowie. Jeśli zachodzi potrzeba owinięcia identyfikatorów
- cudzysłowami należy to zrobić samodzielnie za pomocą metody
- <methodname>quoteIdentifier()</methodname>.
- </para>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example3">
- <title>Przekazanie do fabryki opcji sterownika PDO</title>
- <programlisting language="php"><![CDATA[
- $pdoParams = array(
- PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'driver_options' => $pdoParams
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- echo $db->getConnection()
- ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.connecting.parameters.example4">
- <title>Przekazanie do fabryki opcji serializacji</title>
- <programlisting language="php"><![CDATA[
- $options = array(
- Zend_Db::ALLOW_SERIALIZATION => false
- );
- $params = array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'options' => $options
- );
- $db = Zend_Db::factory('Pdo_Mysql', $params);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.connecting.getconnection">
- <title>Zarządzanie leniwymi połączeniami</title>
- <para>
- Utworzenie instancji klasy adaptera nie powoduje natychmiastowego połączenia
- z serwerem bazy danych. Adapter zachowuje parametry połączenia ale łączy się
- na żądanie - w momencie pierwszego wywołania zapytania. Dzięki temu zainicjowanie
- adaptera jest szybkie i tanie. Można utworzyć adapter nawet jeśli nie jest
- się pewnym czy wykonanie jakiegokolwiek zapytania przy danym połączeniu będzie
- niezbędne.
- </para>
- <para>
- Jeśli zajdzie potrzeba zmuszenia adaptera do połączenia z bazą danych,
- należy wówczas wywołać metodę <methodname>getConnection()</methodname>.
- Zwraca ona obiekt połączenia odpowiednio do rozszerzenia
- <acronym>PHP</acronym> używanego do połączenia. Jeśli
- używa się adaptera korzystającego z <acronym>PDO</acronym>, to metoda
- <methodname>getConnection()</methodname>, po zainicjowaniu połączenia
- z serwerem bazy danych, zwróci obiekt <acronym>PDO</acronym>.
- </para>
- <para>
- Możliwość wymuszenia połączenia z bazą danych może być przydatna gdy chce się
- złapać wyjątki rzucane przez adapter powstałe w rezultacie podania złych danych
- uwierzytelniających lub innych błędów połączenia. Te wyjątki nie są rzucane dopóki
- nie jest ustanowiona próba połączenia, więc można uprościć kod aplikacji i obsłużyć
- je w jednym miejscu. W przeciwnym razie należałoby je przechwycać w momencie
- wywołania pierwszego zapytania do bazy danych.
- </para>
- <para>
- Dodatkowo adapter może zostać poddany serializacji i przechowany
- np. w zmiennej sesyjnej.
- Może to być pomocne nie tylko dla adaptera ale również z punktu widzenia obiektów,
- które z niego korzystają, takich jak <classname>Zend_Db_Select</classname>.
- Domyślnie serializacja adapterów jest dozwolona ale jeśli jest taka
- potrzeba - można ją wyłączyć poprzez podanie opcji
- <constant>Zend_Db::ALLOW_SERIALIZATION</constant> z wartością
- <constant>FALSE</constant> (przykład niżej).
- Aby pozostać w zgodzie z zasadą leniwego połączenia, adapter nie połączy się
- automatycznie po odserializowaniu. Należy zatem
- wywołać metodę <methodname>getConnection()</methodname>.
- Można również zmusić adapter aby po odserializowaniu łączył się z bazą
- danych automatycznie poprzez podanie opcji
- <constant>Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE</constant>
- z wartością <constant>TRUE</constant>.
- </para>
- <example id="zend.db.adapter.connecting.getconnection.example">
- <title>Obsługa wyjątków połączenia</title>
- <programlisting language="php"><![CDATA[
- try {
- $db = Zend_Db::factory('Pdo_Mysql', $parameters);
- $db->getConnection();
- } catch (Zend_Db_Adapter_Exception $e) {
- // przyczyną problemów mogą być złe dane uwierzytelniające lub np. baza danych
- // nie jest uruchomiona
- } catch (Zend_Exception $e) {
- // przyczyną może być np. problem z załadowaniem odpowiedniej klasy adaptera
- }
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.example-database">
- <title>Przykładowa baza danych</title>
- <para>
- W dokumentacji klas <classname>Zend_Db</classname> używany jest prosty zestaw tabel w
- celu zilustrowania użycia klas i metod. Te tabele mogą przechowywać dane związane z
- przechowywaniem błędów (bugs) powstałych podczas rozwijania projektu informatycznego.
- Baza danych zawiera cztery tabele:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>accounts</emphasis> przechowuje informacje o każdym użytkowniku
- bazy danych błędów.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>products</emphasis> przechowuje informacje o każdym produkcie,
- dla którego można zapisać wystąpienie usterki.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>bugs</emphasis> przechowuje informacje o błędach, włączając
- jego obecny stan, osobę zgłaszającą, osobę przypisaną do rozwiązania
- problemu oraz osobę przeznaczoną do zweryfikowania poprawności
- zastosowanego rozwiązania.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>bugs_products</emphasis> przechowuje relację pomiędzy usterkami
- a produktami. To odzwierciedla połączenie wiele-do-wielu, ponieważ dany błąd
- może się odnosić do wielu produktów a jeden produkt może posiadać wiele usterek.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Poniższy pseudokod definicji danych <acronym>SQL</acronym> opisuje tabele z tego
- przykładu. Te tabele są bardzo często używane w testach jednostkowych
- <classname>Zend_Db</classname>.
- </para>
- <programlisting language="sql"><![CDATA[
- CREATE TABLE accounts (
- account_name VARCHAR(100) NOT NULL PRIMARY KEY
- );
- CREATE TABLE products (
- product_id INTEGER NOT NULL PRIMARY KEY,
- product_name VARCHAR(100)
- );
- CREATE TABLE bugs (
- bug_id INTEGER NOT NULL PRIMARY KEY,
- bug_description VARCHAR(100),
- bug_status VARCHAR(20),
- reported_by VARCHAR(100) REFERENCES accounts(account_name),
- assigned_to VARCHAR(100) REFERENCES accounts(account_name),
- verified_by VARCHAR(100) REFERENCES accounts(account_name)
- );
- CREATE TABLE bugs_products (
- bug_id INTEGER NOT NULL REFERENCES bugs,
- product_id INTEGER NOT NULL REFERENCES products,
- PRIMARY KEY (bug_id, product_id)
- );
- ]]></programlisting>
- <para>
- Należy zwrócić uwagę, iż tabela 'bugs' zawiera wiele kluczy obcych
- odnoszących się do tabeli 'accounts'. Każdy z nich może prowadzić do
- innego wiersza tabeli 'accounts' w ramach jednego bugu.
- </para>
- <para>
- Poniższy diagram ilustruje fizyczny model danych przykładowej bazy danych
- </para>
- <para>
- <inlinegraphic width="387" scale="100" align="center" valign="middle"
- fileref="figures/zend.db.adapter.example-database.png" format="PNG" />
- </para>
- </sect2>
- <sect2 id="zend.db.adapter.select">
- <title>Pobranie rezultatów zapytania</title>
- <para>
- Ta część opisuje metody klasy adaptera za pomocą których można wywołać
- zapytania <acronym>SELECT</acronym> oraz pobrać ich rezultaty.
- </para>
- <sect3 id="zend.db.adapter.select.fetchall">
- <title>Pobranie całego zbioru rezultatów</title>
- <para>
- Za pomocą metody <methodname>fetchAll()</methodname> można wywołać zapytanie
- <acronym>SQL</acronym> <acronym>SELECT</acronym> oraz pobrać jego rezultaty
- w jednym kroku.
- </para>
- <para>
- Pierwszym argumentem metody jest łańcuch znaków zawierający polecenie
- <acronym>SELECT</acronym>. Alternatywnie, w pierwszym argumencie można umieścić
- obiekt klasy <link linkend="zend.db.select">Zend_Db_Select</link>. Adapter
- automatycznie dokonuje konwersji tego obiektu do łańcucha znaków zawierającego
- zapytanie <acronym>SELECT</acronym>.
- </para>
- <para>
- Drugi argument metody <methodname>fetchAll()</methodname> to tablica wartości
- używanych do zastąpienia parametrów wiązanych w zapytaniu <acronym>SQL</acronym>.
- </para>
- <example id="zend.db.adapter.select.fetchall.example">
- <title>Użycie metody fetchAll()</title>
- <programlisting language="php"><![CDATA[
- $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
- $result = $db->fetchAll($sql, 2);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetch-mode">
- <title>Zmiana trybu zwracania danych</title>
- <para>
- Domyślnie <methodname>fetchAll()</methodname> zwraca tablicę wierszy, z których
- każdy jest tablicą asocjacyjną. Kluczami tablicy asocjacyjnej są kolumny lub ich
- aliasy podane w zapytaniu <acronym>SELECT</acronym>.
- </para>
- <para>
- Można ustawić inny tryb zwracania rezultatów poprzez metodę
- <methodname>setFetchMode()</methodname>. Dopuszczalne tryby są identyfikowane
- przez stałe:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Zend_Db::FETCH_ASSOC</emphasis>:
- zwraca dane w postaci tablicy tablic asocjacyjnych.
- Klucze tablicy asocjacyjnej
- to nazwy kolumn. To jest domyślny tryb zwrotu danych w klasach
- <classname>Zend_Db_Adapter</classname>.
- </para>
- <para>
- Należy zwrócić uwagę na fakt iż jeśli lista kolumn do zwrotu
- zawiera więcej niż jedną kolumnę o określonej nazwie,
- np. jeśli pochodzą one z różnych tabel
- połączonych klauzulą <acronym>JOIN</acronym>, to w asocjacyjnej
- tablicy wynikowej może być tylko jeden klucz o podanej nazwie.
- Jeśli używany jest tryb <acronym>FETCH_ASSOC</acronym>,
- należy upewnić się, że kolumny w zapytaniu
- <acronym>SELECT</acronym> posiadają aliasy, dzięki czemu rezultat zapytania
- będzie zawierał unikatowe nazwy kolumn.
- </para>
- <para>
- Domyślnie, łańcuchy znaków z nazwami kolumn są zwracane w taki sposób w jaki
- zostały otrzymane przez sterownik bazy danych. Przeważnie jest odpowiada to
- stylowi nazw kolumn używanego rodzaju bazy danych. Dzięki opcji
- <constant>Zend_Db::CASE_FOLDING</constant> można określić wielkość
- zwracanych znaków.
- Opcji tej można użyć podczas inicjowania adaptera.
- Przykład: <xref linkend="zend.db.adapter.connecting.parameters.example1" />.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Zend_Db::FETCH_NUM</emphasis>:
- zwraca dane jako tablicę tablic. Indeksami tablicy są liczby całkowite
- odpowiadające pozycji danej kolumny w liście <acronym>SELECT</acronym>
- zapytania.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Zend_Db::FETCH_BOTH</emphasis>:
- zwraca dane jako tablicę tablic. Kluczami tablicy są zarówno łańcuchy znaków
- (tak jak w trybie FETCH_ASSOC) oraz liczby całkowite (tak jak w trybie
- FETCH_NUM). Należy zwrócić uwagę na fakt iż liczba elementów
- tablicy wynikowej będzie dwukrotnie większa niż w przypadku
- użycia trybów FETCH_ASSOC lub FETCH_NUM.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Zend_Db::FETCH_COLUMN</emphasis>:
- zwraca dane jako tablicę wartości. Wartości odpowiadają rezultatom
- zapytania przypisanym jednej kolumnie zbioru wynikowego.
- Domyślnie, jest to pierwsza kolumna,
- indeksy rozpoczynają się od 0.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Zend_Db::FETCH_OBJ</emphasis>:
- zwraca dane jako tablicę obiektów. Domyślną klasą jest wbudowana
- w <acronym>PHP</acronym> klasa stdClass.
- Kolumny rezultatu zapytania stają się właściwościami powstałego obiektu.
- </para>
- </listitem>
- </itemizedlist>
- <example id="zend.db.adapter.select.fetch-mode.example">
- <title>Użycie metody setFetchMode()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
- // $result jest tablicą obiektów
- echo $result[0]->bug_description;
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchassoc">
- <title>Pobranie rezultatów jako tablicy asocjacyjnej</title>
- <para>
- Metoda <methodname>fetchAssoc()</methodname> zwraca dane w formie tablicy tablic
- asocjacyjnych, niezależnie od wartości ustalonej jako tryb
- zwracania rezultatów zapytania.
- </para>
- <example id="zend.db.adapter.select.fetchassoc.example">
- <title>Użycie fetchAssoc()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
- // $result staje się tablicą tablic asocjacyjnych, mimo ustawionego
- // trybu zwracania rezultatów zapytania
- echo $result[0]['bug_description'];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchcol">
- <title>Zwrócenie pojedynczej kolumny ze zbioru wynikowego</title>
- <para>
- Metoda <methodname>fetchCol()</methodname> zwraca dane w postaci tablicy wartości
- niezależnie od wartości ustalonej jako tryb zwrcania rezultatów zapytania. Ta
- metoda zwraca pierwszą kolumnę ze zbioru powstałego na skutek wywołania zapytania.
- Inne kolumny znajdujące się w tym zbiorze są ignorowane. Aby zwrócić inną niż
- pierwsza kolumnę należy skorzystać z przykładu
- <xref linkend="zend.db.statement.fetching.fetchcolumn" />.
- </para>
- <example id="zend.db.adapter.select.fetchcol.example">
- <title>Użycie fetchCol()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchCol(
- 'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
- // zawiera bug_description; bug_id nie zostanie zwrócona
- echo $result[0];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchpairs">
- <title>Zwrócenie ze zbioru wynikowego par klucz-wartość</title>
- <para>
- Metoda <methodname>fetchPairs()</methodname> zwraca dane w postaci tablicy
- par klucz-wartość. Zwracana jest to tablica asocjacyjna z pojedynczą wartością
- w każdym polu. Wartości z pierwszej kolumny zapytania <acronym>SELECT</acronym>
- stają się kluczami tablicy wynikowej zaś wartości drugiej zostają umieszczone
- jako wartości tablicy. Pozostałe kolumny zwracane przez zapytanie są ignorowane.
- </para>
- <para>
- Należy konstruować zapytanie <acronym>SELECT</acronym> w taki sposób aby pierwsza
- kolumna posiadała unikalne wartości. W przeciwnym wypadku wartości
- tablicy asocjacyjnej zostaną nadpisane.
- </para>
- <example id="zend.db.adapter.select.fetchpairs.example">
- <title>Użycie fetchPairs()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
- echo $result[2];
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchrow">
- <title>Zwrócenie pojedynczego wiersza ze zbioru wynikowego</title>
- <para>
- Metoda <methodname>fetchRow()</methodname> pobiera dane używając bieżącego
- trybu zwracania rezultatów ale zwraca jedynie pierwszy wiersz ze zbioru
- wynikowego.
- </para>
- <example id="zend.db.adapter.select.fetchrow.example">
- <title>Using fetchRow()</title>
- <programlisting language="php"><![CDATA[
- $db->setFetchMode(Zend_Db::FETCH_OBJ);
- $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
- // $result to pojedynczy obiekt a nie tablica obiektów
- echo $result->bug_description;
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.select.fetchone">
- <title>Zwrócenie pojedynczej wartości ze zbioru wynikowego</title>
- <para>
- Metoda <methodname>fetchOne()</methodname> można opisać jako kombinacja
- <methodname>fetchRow()</methodname> oraz <methodname>fetchCol()</methodname>
- bo zwraca dane pochodzące z pierwszego wiersza zbioru wynikowego ograniczając
- kolumny do pierwszej w wierszu. Ostatecznie zostaje zwrócona pojedyncza
- wartość skalarna a nie tablica czy obiekt
- </para>
- <example id="zend.db.adapter.select.fetchone.example">
- <title>Using fetchOne()</title>
- <programlisting language="php"><![CDATA[
- $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
- // pojedyncza wartość string
- echo $result;
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.write">
- <title>Zapisywanie zmian do bazy danych</title>
- <para>
- Adaptera klasy można użyć również do zapisania nowych, bądź do zmiany
- istniejących danych w bazie. Ta część opisuje metody włąściwe dla tych operacji.
- </para>
- <sect3 id="zend.db.adapter.write.insert">
- <title>Dodawanie danych</title>
- <para>
- Za pomocą metody <methodname>insert()</methodname> można dodać nowe wiersze
- do tabeli bazy danych. Jej pierwszym argumentem jest łańcuch znaków oznaczający
- nazwę tabeli. Drugim - tablica asocjacyjna z odwzorowaniem nazw kolumn i wartości
- jakie mają zostać w nich zapisane.
- </para>
- <example id="zend.db.adapter.write.insert.example">
- <title>Dodawanie danych do tabeli</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'created_on' => '2007-03-22',
- 'bug_description' => 'Something wrong',
- 'bug_status' => 'NEW'
- );
- $db->insert('bugs', $data);
- ]]></programlisting>
- </example>
- <para>
- Kolumny, które nie zostały podane w tablicy z danymi nie będą umieszczone
- w zapytaniu na zasadzie analogicznej do użycia polecenia
- <acronym>SQL</acronym> <acronym>INSERT</acronym>:
- Jeśli kolumna ma podaną wartość domyślną (<acronym>DEFAULT</acronym>)
- to ta wartość zostanie zapisana w nowym wierszu.
- W przeciwnym przypadku kolumna nie będzie miała żadnej
- wartości (<constant>NULL</constant>).
- </para>
- <para>
- Domyślnym sposobem zapisu danych jest użycie parametrów wiązanych.
- Dzięki temu ryzyko wystąpienia niektórych form zagrożenia
- bezpieczeństwa aplikacji jest ograniczone.
- W tablicy z danymi nie trzeba używać unikania
- lub umieszczania wartości w cudzysłowiu.
- </para>
- <para>
- Może wystąpić potrzeba potraktowania wartości w tablicy danych jako wyrażeń
- <acronym>SQL</acronym>. W takim wypadku nie powinno się stosować
- umieszczania w cudzysłowiu.
- Domyślnie wszystkie podane wartości string są traktowane jak literały.
- Aby upewnić się, że
- wartość jest wyrażeniem <acronym>SQL</acronym> i nie powinna zostać umieszczona w
- cudzysłowie, należy ją podać jako obiekt klasy
- <classname>Zend_Db_Expr</classname> zamiast
- prostego łańcucha znaków.
- </para>
- <example id="zend.db.adapter.write.insert.example2">
- <title>Umieszczanie wyrażeń w tabeli</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'created_on' => new Zend_Db_Expr('CURDATE()'),
- 'bug_description' => 'Something wrong',
- 'bug_status' => 'NEW'
- );
- $db->insert('bugs', $data);
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.write.lastinsertid">
- <title>Pobranie wygenerowanej wartości</title>
- <para>
- Niektóre systemy zarządzania bazą danych wspierają klucze pierwotne o automatycznie
- zwiększanych wartościach. Tabela zdefiniowana w ten sposób generuje wartość klucza
- pierwotnego automatycznie przy każdym poleceniu <acronym>INSERT</acronym>.
- Wartością zwracaną przez metodę
- <methodname>insert()</methodname> <emphasis>nie</emphasis> jest
- ostatni zapisany identyfikator, ponieważ tabela mogła nie posiadać automatycznie
- inkrementowanej kolumny.
- Zamiast tego wartością zwrotną jest ilość zapisanych wierszy (przeważnie 1).
- </para>
- <para>
- Jeśli tabela jest zdefiniowana za pomocą automatycznego klucza pierwotnego to można
- użyć metody <methodname>lastInsertId()</methodname>.
- Po udanym dodaniu wiersza metoda
- ta zwraca ostatnią wartość klucza wygenerowaną w ramach bieżącego połączenia.
- </para>
- <example id="zend.db.adapter.write.lastinsertid.example-1">
- <title>Użycie lastInsertId() dla automatycznego klucza pierwotnego</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // zwrócenie ostatniej wartości wygenerowanej przez automatyczną kolumnę
- $id = $db->lastInsertId();
- ]]></programlisting>
- </example>
- <para>
- Niektóre systemy zarządzania bazą danych wspierają obiekt sekwencji, który służy
- do generowania unikalnych wartości, które mogą posłużyć jako klucz pierwotny.
- Aby obsługiwać również sekwencje metoda <methodname>lastInsertId()</methodname>
- akceptuje dodatkowe dwa argumenty. Pierwszym z nich jest nazwa tabeli zaś
- drugim - nazwa kolumny. Założona jest konwencja według której sekwencja ma nazwę
- składającą się z nazwy tabeli oraz kolumny do której generuje wartości z dodatkowym
- sufiksem "_seq". Podstawą tego założenia są domyślne ustawienia PostgreSQL.
- Przykładowo tabela "bugs" z kluczem pierwotnym w kolumnie "bug_id"
- będzie używała sekwencji o nazwie "bugs_bug_id_seq".
- </para>
- <example id="zend.db.adapter.write.lastinsertid.example-2">
- <title>Użycie lastInsertId() dla sekwencji</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_bug_id_seq'
- $id = $db->lastInsertId('bugs', 'bug_id');
- // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_seq'
- $id = $db->lastInsertId('bugs');
- ]]></programlisting>
- </example>
- <para>
- Jeśli nazwa obiektu sekwencji nie podąża za tą konwencją można użyć metody
- <methodname>lastSequenceId()</methodname>, która przyjmuje pojedynczy łańcuch
- znaków - nazwę sekwencji - jako argument.
- </para>
- <example id="zend.db.adapter.write.lastinsertid.example-3">
- <title>Użycie lastSequenceId()</title>
- <programlisting language="php"><![CDATA[
- $db->insert('bugs', $data);
- // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_id_gen'
- $id = $db->lastSequenceId('bugs_id_gen');
- ]]></programlisting>
- </example>
- <para>
- Dla systemów zarządzania bazą danych które nie wspierają sekwencji, włączając MySQL,
- Microsoft <acronym>SQL</acronym> Server, oraz SQLite dodatkowe argumenty podane do
- metody <methodname>lastInsertId()</methodname> są ignorowane a zwrócona jest
- ostatnia wartość wygenerowana dla dowolnej tabeli poprzez polecenie
- <acronym>INSERT</acronym>
- podczas bieżącego połączenia. Dla tych <acronym>RDBMS</acronym> metoda
- <methodname>lastSequenceId()</methodname> zawsze zwraca <constant>NULL</constant>.
- </para>
- <note>
- <title>Dlaczego nie należy używać "SELECT MAX(id) FROM table"?</title>
- <para>
- Powyższe zapytanie często zwraca ostatni klucz pierwotny, jaki został zapisany
- w wierszu tabeli. Ten sposób nie jest jednak bezpieczny w przypadku, gdy
- wiele klientów zapisuje rekordy do bazy danych. Jest możliwe, że w momencie
- pomiędzy zapisaniem jednego rekordu a zapytaniem o
- <methodname>MAX(id)</methodname>, do tabeli zostanie zapisany kolejny rekord,
- wprowadzony przez innego użytkownika. Przez to zwrócona wartość nie będzie
- identyfikowała pierwszego wprowadzonego wiersza tylko drugi - wprowadzony przez
- inne połączenie. Nie ma pewnego sposobu na wykrycie, że do takiego zdarzenia
- doszło.
- </para>
- <para>
- Zastosowanie mocnej izolacji transakcji, tak jak przy trybie
- "repeatable read" może pomóc w ograniczeniu ryzyka wystąpienia takiej
- sytuacji ale niektóre systemy zarządzania bazą danych nie wspierają
- izolacji transakcji w wystarczającym stopniu lub aplikacja może
- intencjonalnie korzystać jedynie z niskiego trybu izolacji transakcji.
- </para>
- <para>
- Dodatkowo, używanie wyrażeń takich jak "MAX(id)+1" do generowania
- nowych wartości klucza głównego nie jest bezpieczne bo
- dwa połączenia mogą wykonać to zapytanie
- praktycznie jednocześnie i w rezultacie próbować użyć jednakowej wartości
- dla kolejnego polecenia <acronym>INSERT</acronym>.
- </para>
- <para>
- Wszystkie systemy zarządzania bazą danych udostępniają
- mechanizmy służące generowaniu
- unikalnych wartości oraz zwracaniu ostatniej z nich.
- Mechanizmy te intencjonalnie działają poza zasięgiem izolacji
- transakcji więc nie jest możliwe aby wartość wygenerowana dla jednego
- klienta pojawiła się jako ostatnia wygenerowana dla innego połączenia.
- </para>
- </note>
- </sect3>
- <sect3 id="zend.db.adapter.write.update">
- <title>Aktualizacja danych</title>
- <para>
- Aktualizacji wierszy tabeli w bazie danych można dokonać poprzez metodę adaptera
- <methodname>update()</methodname> . Metoda przyjmuje trzy argumenty: pierwszym
- jest nazwa tabeli; drugim - tablica asocjacyjna mapująca kolumny, które mają ulec
- zmianie oraz wartości jakie kolumny przybiorą; trzecim - warunek
- wyznaczający wiersze do zmiany.
- </para>
- <para>
- Wartości w tablicy z danymi są traktowane jak literały znakowe. Należy zapoznać
- się z akapitem <xref linkend="zend.db.adapter.write.insert" /> aby uzyskać więcej
- informacji na temat użyci w niej wyrażeń <acronym>SQL</acronym>.
- </para>
- <para>
- Trzecim argumentem metody jest string zawierający wyrażenie <acronym>SQL</acronym>
- będące kryterium wyznaczającym wiersze do zmiany. Wartości i identyfikatory w tym
- argumencie nie są umieszczane w cudzysłowie ani unikane. Należy, więc, zadbać o to
- samemu. Należy zapoznać się z akapitem <xref linkend="zend.db.adapter.quoting" />
- aby zasięgnąć dodatkowych informacji.
- </para>
- <para>
- Wartością zwracaną jest ilość wierszy zmienionych przez operację aktualizacji.
- </para>
- <example id="zend.db.adapter.write.update.example">
- <title>Aktualizacja wierszy</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $n = $db->update('bugs', $data, 'bug_id = 2');
- ]]></programlisting>
- </example>
- <para>
- Jeśli trzeci argument nie zostanie podany to wszystkie wiersze w tabeli
- zostaną zaktualizowane zgodnie z kolumnami i wartościami podanymi w
- drugim argumencie.
- </para>
- <para>
- Jeśli trzeci argument zostanie podany jako tablica łańcuchów znakowych to
- w zapytaniu łańcuchy zostaną połączone za pomocą operatorów
- <constant>AND</constant>.
- </para>
- <para>
- Przy podaniu trzeciego argumentu jako tablicy tablic, ich wartości
- zostaną automatycznie
- otoczone cudzysłowami i umieszczone w kluczach tych tablic. Po czym zostaną
- połączone za pomocą operatorów <constant>AND</constant>.
- </para>
- <example id="zend.db.adapter.write.update.example-array">
- <title>Aktualizacja wierszy tablicy za pomocą tablicy wyrażeń</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $where[] = "reported_by = 'goofy'";
- $where[] = "bug_status = 'OPEN'";
- $n = $db->update('bugs', $data, $where);
- // Powstałe wyrażenie SQL to:
- // UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
- // WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
- ]]></programlisting>
- </example>
- <example id="zend.db.adapter.write.update.example-arrayofarrays">
- <title>Aktualizacja wierszy tablicy za pomocą tablicy tablic</title>
- <programlisting language="php"><![CDATA[
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $where['reported_by = ?'] = 'goofy';
- $where['bug_status = ?'] = 'OPEN';
- $n = $db->update('bugs', $data, $where);
- // Powstałe wyrażenie SQL to:
- // UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
- // WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.write.delete">
- <title>Usuwanie danych</title>
- <para>
- Usuwania danych można dokonać używając metody <methodname>delete()</methodname>.
- Przyjmuje ona dwa argumenty: pierwszym z nich jest łańcuch znaków z nazwą tabeli;
- Drugim - warunek określający wiersze do usunięcia.
- </para>
- <para>
- Drugi argument to string zawierający wyrażenie <acronym>SQL</acronym> użyte jako
- kryterium wyznaczania usuwanych wierszy. Wartości i identyfikatory nie są
- unikane ani umieszczane w cudzysłowie - należy zatroszczyć się o to samemu. Aby
- dowiedzieć się więcej na ten temat
- można skorzystać z akapitu <xref linkend="zend.db.adapter.quoting" />.
- </para>
- <para>
- Wartość zwrotna to ilość wierszy, jakie uległy zmianie w wyniku zadziałania
- operacji usuwania.
- </para>
- <example id="zend.db.adapter.write.delete.example">
- <title>Usuwanie wierszy</title>
- <programlisting language="php"><![CDATA[
- $n = $db->delete('bugs', 'bug_id = 3');
- ]]></programlisting>
- </example>
- <para>
- Jeśli drugi argument nie zostanie podany to wszystkie wiersze z tabeli
- ulegną usunięciu.
- </para>
- <para>
- Jeśli drugi argument zostanie podany jako tablica łańcuchów znaków to
- te łańcuchy ulegną konkatenacji jako wyrażenia logiczne połączone
- operatorem <constant>AND</constant>.
- </para>
- <para>
- Jeśli trzeci argument będzie tablicą tablic to jej wartości zostaną
- automatycznie otoczone cudzysłowami i umieszczona w kluczach tablic. Potem
- zostaną połączone razem za pomocą operatora <constant>AND</constant>.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.quoting">
- <title>Umieszczanie wartości i identyfikatorów w cudzysłowie</title>
- <para>
- Podczas tworzenia zapytań <acronym>SQL</acronym> często dochodzi do sytuacji, w której
- niezbędne jest umieszczenie wartości zmiennych <acronym>PHP</acronym> w wyrażeniach
- <acronym>SQL</acronym>. Stanowi to zagrożenie, ponieważ jeśli wartość
- łańcuchowej zmiennej <acronym>PHP</acronym> zawiera określone znaki, takie jak symbol
- cudzysłowu, to mogą one spowodować błąd w poleceniu <acronym>SQL</acronym>. Poniżej
- znajduje się przykład zapytania zawierającego niespójną liczbę symboli cudzysłowu:
- <programlisting language="php"><![CDATA[
- $name = "O'Reilly";
- $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
- ]]></programlisting>
- </para>
- <para>
-
-
- Zagrożenie potęguje fakt iż podobne błędy mogą zostać wykorzystane przez osobę
- próbującą zmanipulować działanie funkcji aplikacji. Jeśli takiej osobie
- uda się wpłynąć na wartość zmiennej <acronym>PHP</acronym> poprzez
- parametr <acronym>HTTP</acronym>
- (bądź inny mechanizm), to będzie mogła zmienić zapytanie <acronym>SQL</acronym>
- tak by dokonywało operacji zupełnie niezamierzonych przez twórców, takich jak
- zwrócenie danych, do których osoba nie powinna mieć dostępu. To jest poważny i szeroko
- rozpowszechniony sposób łamania zabezpieczeń aplikacji znany pod nazwą "SQL Injection"
- (wstrzyknięcie SQL - <ulink url="http://en.wikipedia.org/wiki/SQL_Injection">
- http://en.wikipedia.org/wiki/SQL_Injection</ulink>).
- </para>
- <para>
- Adaptery klasy <classname>Zend_Db</classname> udostępniają funkcje przydatne
- do zredukowania zagrożenia atakiem <acronym>SQL</acronym> Injection w kodzie
- <acronym>PHP</acronym>.
- Przyjętym rozwiązaniem jest unikanie znaków specjalnych takich jak cudzysłów w
- wartościach zmiennych <acronym>PHP</acronym>
- przed umieszczeniem ich w poleceniu <acronym>SQL</acronym>.
- Takie podejście zapewnia ochronę przed przypadkową jak i intencjonalną zmianą
- znaczenia poleceń <acronym>SQL</acronym> przez
- zmienne <acronym>PHP</acronym> zawierające znaki specjalne.
- </para>
- <sect3 id="zend.db.adapter.quoting.quote">
- <title>Użycie quote()</title>
- <para>
- Metoda <methodname>quote()</methodname> przyjmuje pojedynczy
- argument - łańcuch znaków.
- Na wyjściu zwraca podany argument ze wszystkimi znakami specjalnymi
- poddanymi uniknięciu w sposób właściwy dla używanego
- <acronym>RDBMS</acronym> i otoczony znakami ograniczającymi
- łańcuchy znakowe. Standardowym znakiem ograniczającym
- stringi w <acronym>SQL</acronym> jest pojedynczy cudzysłów (').
- </para>
- <example id="zend.db.adapter.quoting.quote.example">
- <title>Użycie quote()</title>
- <programlisting language="php"><![CDATA[
- $name = $db->quote("O'Reilly");
- echo $name;
- // 'O\'Reilly'
- $sql = "SELECT * FROM bugs WHERE reported_by = $name";
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
- ]]></programlisting>
- </example>
- <para>
- Należy zwrócić uwagę, że wartość zwrotna metody <methodname>quote()</methodname>
- zawiera znaki ograniczające stringi. Jest to zachowanie różne od niektórych funkcji
- które unikają specjalne znaki ale nie ujmują całego łańcucha w znaki ograniczające,
- tak jak <ulink url="http://www.php.net/mysqli_real_escape_string">
- mysql_real_escape_string()</ulink>.
- </para>
- <para>
- Wartości mogą wymagać umieszczenia w cudzysłowach lub nie, zgodnie z
- kontekstem używanego typu danych <acronym>SQL</acronym>.
- W przypadku niektórych rodzajów systemów zarządzania
- bazą danych liczby całkowite nie mogą być ograniczane cudzysłowami
- jeśli są porównywane z kolumną lub wyrażeniem zwracającym inną liczbę całkowitą.
- Innymi słowy, poniższy zapis może wywołać błąd w niektórych
- implementacjach <acronym>SQL</acronym> zakładając, że
- <property>intColumn</property> jest określona
- typem danych <constant>INTEGER</constant>.
- <programlisting language="php"><![CDATA[
- SELECT * FROM atable WHERE intColumn = '123'
- ]]></programlisting>
- </para>
- <para>
- Można użyć opcjonalnego, drugiego argumentu metody <methodname>quote()</methodname>
- aby określić typ danych <acronym>SQL</acronym> i ograniczyć stosowanie cudzysłowu.
- </para>
- <example id="zend.db.adapter.quoting.quote.example-2">
- <title>Użycie quote() z podanym typem danych SQL</title>
- <programlisting language="php"><![CDATA[
- $value = '1234';
- $sql = 'SELECT * FROM atable WHERE intColumn = '
- . $db->quote($value, 'INTEGER');
- ]]></programlisting>
- </example>
- <para>
- Każda klasa <classname>Zend_Db_Adapter</classname> ma zapisane nazwy numerycznych
- typów danych <acronym>SQL</acronym> odpowiednio do swojego rodzaju
- <acronym>RDBMS</acronym>.
- Zamiast tego można w tym miejscu również korzystać ze stałych
- <constant>Zend_Db::INT_TYPE</constant>,
- <constant>Zend_Db::BIGINT_TYPE</constant> oraz
- <constant>Zend_Db::FLOAT_TYPE</constant> aby uniezależnić kod
- od rodzaju bazy danych.
- </para>
- <para>
- <classname>Zend_Db_Table</classname> automatycznie określa
- typy danych <acronym>SQL</acronym>
- dla metody <methodname>quote()</methodname> podczas generowania
- zapytań <acronym>SQL</acronym> odnoszących się do klucza pierwotnego tabeli.
- </para>
- </sect3>
- <sect3 id="zend.db.adapter.quoting.quote-into">
- <title>Użycie quoteInto()</title>
- <para>
- Najbardziej typowym przypadkiem użycia cudzysłowu do ograniczania zmiennych jest
- umieszczenie zmiennej <acronym>PHP</acronym> w zapytaniu <acronym>SQL</acronym>.
- Aby to osiągnąć można użyć metody <methodname>quoteInto()</methodname>.
- Przyjmuje ona dwa argumenty: pierwszym jest łańcuch znaków zawierający
- symbol "?", który zostanie zastąpiony; drugim jest zmienna
- <acronym>PHP</acronym>, która ma trafić na miejsce "?".
- </para>
- <para>
- Zastępowany symbol jest używany przez wielu producentów baz danych do oznaczenia
- pozycyjnych parametrów wiązanych ale metoda <methodname>quoteInto()</methodname>
- jedynie emuluje takie parametry. W wyniku jej działania wartość zmiennej jest
- zwyczajnie umieszczana w łańcuchu z zapytaniem, po wstępnym uniknięciu specjalnych
- znaków i umieszczeniu w cudzysłowie. Prawdziwa implementacja parametrów wiązanych
- zakłada separację łańcucha znaków polecenia <acronym>SQL</acronym> od samych
- parametrów oraz wstępne parsowanie polecenia na serwerze bazy danych.
- </para>
- <example id="zend.db.adapter.quoting.quote-into.example">
- <title>Użycie quoteInto()</title>
- <programlisting language="php"><![CDATA[
- $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
- ]]></programlisting>
- </example>
- <para>
- Można użyć opcjonalnego, trzeciego parametru metody
- <methodname>quoteInto()</methodname>
- aby określić typ danych <acronym>SQL</acronym>.
- Numeryczne typy danych (w przeciwieństwie
- do innych typów) nie podlegają umieszczaniu w cudzysłowie.
- </para>
- <example id="zend.db.adapter.quoting.quote-into.example-2">
- <title>Użycie quoteInto() z podaniem typu danych SQL</title>
- <programlisting language="php"><![CDATA[
- $sql = $db
- ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
- echo $sql;
- // SELECT * FROM bugs WHERE reported_by = 1234
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.adapter.quoting.quote-identifier">
- <title>Użycie quoteIdentifier()</title>
- <para>
- Wartości nie są jedyną częścią składni polecenia <acronym>SQL</acronym>, która może
- być zmienna. W przypadku użycia zmiennych <acronym>PHP</acronym> do określenia
- tabel, kolumn lub innych identyfikatorów zapytania <acronym>SQL</acronym>,
- może zajść potrzeba umieszczenia również tych elementów w cudzysłowie.
- Domyślnie identyfikatory <acronym>SQL</acronym> muszą przestrzegać określonych
- reguł - podobnie jak w <acronym>PHP</acronym> oraz większości innych
- języków programowania. Przykładem takiej reguły jest zakaz używania spacji
- lub określonych znaków interpunkcyjnych, specjalnych ani też znaków spoza ASCII.
- Poza tym istnieje lista określonych słów, które służą
- do tworzenia zapytań - ich też nie powinno się używać jako identyfikatorów.
- </para>
- <para>
- Mimo to <acronym>SQL</acronym> posiada
- <emphasis>ograniczone identyfikatory</emphasis> (delimited identifiers),
- dzięki którym można skorzystać z większego wachlarza znaków
- do nazywania obiektów.
- Jeśli określony identyfikator zostanie ograniczony odpowiednim
- rodzajem cudzysłowu to będzie można użyć znaków, które bez tego ograniczenia
- spowodowałyby błąd. Identyfikatory ograniczone mogą zawierać spacje,
- znaki interpunkcyjne czy lokalne litery.
- Można nawet używać zarezerwowanych słów <acronym>SQL</acronym> jeśli
- zostaną otoczone odpowiednimi znakami ograniczającymi.
- </para>
- <para>
- Metoda <methodname>quoteIdentifier()</methodname> zachowuje się podobnie jak
- <methodname>quote()</methodname> ale otacza podany łańcuch znaków za pomocą
- znaków ograniczających zgodnie z rodzajem używanego adaptera.
- Standardowy <acronym>SQL</acronym>
- używa podwójnego cudzysłowu (") jako znaku ograniczającego a większość systemów
- zarządzania bazą danych podąża za tym przykładem. MySQL domyślnie używa znaków
- back-tick (`). Metoda <methodname>quoteIdentifier()</methodname> dokonuje również
- unikania znaków specjalnych znajdujących się w przekazanym argumencie.
- </para>
- <example id="zend.db.adapter.quoting.quote-identifier.example">
- <title>Użycie quoteIdentifier()</title>
- <programlisting language="php"><![CDATA[
- // można użyć tabeli o nazwie takiej samej jak słowo zarezerwowane SQL
- $tableName = $db->quoteIdentifier("order");
- $sql = "SELECT * FROM $tableName";
- echo $sql
- // SELECT * FROM "order"
- ]]></programlisting>
- </example>
- <para>
- W <acronym>SQL</acronym> identyfikatory ograniczone są wrażliwe na wielkość liter,
- w przeciwieństwie do zwykłych identyfikatorów. Przez to, należy upewnić się, że
- pisownia identyfikatora w 100% odpowiada pisowni zapisanej w schemacie, włącznie
- z wielkością liter.
- </para>
- <para>
- W większości przypadków gdzie polecenie <acronym>SQL</acronym> jest
- generowane wewnątrz klas <classname>Zend_Db</classname>,
- domyślnym zachowaniem jest automatyczne ograniczanie
- identyfikatorów. Można to zmienić poprzez opcję
- <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> wywoływaną
- podczas inicjalizacji adaptera.
- Więcej informacji:
- <xref linkend="zend.db.adapter.connecting.parameters.example2" />.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.adapter.transactions">
- <title>Kontrolowanie transakcji bazy danych</title>
- <para>
- W świecie baz danych transakcja to zbiór operacji, który może zostać zapisany
- bądź cofnięty za pomocą jednej instrukcji, nawet jeśli zmiany wynikające z tych operacji
- dotyczyły wielu tabel. Wszystkie zapytania do bazy danych są przeprowadzane w
- kontekście transakcji. Jeśli nie są zarządzane jawnie to sterownik bazy danych używa ich
- w sposób przezroczysty dla użytkownika. Takie podejście nazywa się trybem
- <emphasis>auto-commit</emphasis> - sterownik bazy danych tworzy transakcje dla każdego
- tworzonego polecenia i zapisuje efekty jego działania po każdym wywołaniu polecenia
- <acronym>SQL</acronym>. Domyślnie wszystkie adaptery <classname>Zend_Db</classname>
- działają w trybie <emphasis>auto-commit</emphasis>.
- </para>
- <para>
- Można również bezpośrednio wskazać początek i koniec transakcji i w ten sposób
- kontrolować ilość zapytań <acronym>SQL</acronym> jakie trafiają do zapisania (bądź
- cofnięcia) jako pojedyncza operacja. Aby rozpocząć transakcję należy wywołać metodę
- <methodname>beginTransaction()</methodname>. Następujące po niej polecenia
- <acronym>SQL</acronym> są wykonywane w kontekście wspólnej transakcji do momentu
- zasygnalizowania jej końca.
- </para>
- <para>
- Aby zakończyć transakcję należy użyć metody <methodname>commit()</methodname> lub
- <methodname>rollBack()</methodname>.
- Pierwsza z nich powoduje zapisanie zmian wynikających
- z operacji przeprowadzonych w czasie transakcji.
- Oznacza to, że efekty tych zmian będą
- widoczne w wynikach zapytań wywołanych w ramach innych transakcji.
- </para>
- <para>
- Metoda <methodname>rollBack()</methodname> dokonuje odwrotnej operacji: cofa zmiany
- dokonane podczas transakcji.
- W efekcie wszystkie dane zmienione podczas transakcji zostają cofnięte do
- wartości z momentu przed jej rozpoczęciem. Cofnięcie zmian jednej transakcji nie
- ma wpływu na zmiany dokonane przez inną transakcję trwającą nawet w tym samym czasie.
- </para>
- <para>
- Po skończonej transakcji <classname>Zend_Db_Adapter</classname> wraca
- do trybu auto-commit do momentu ponownego wywołania metody
- <methodname>beginTransaction()</methodname> i ręcznego
- rozpoczęcia nowej transakcji.
- </para>
- <example id="zend.db.adapter.transactions.example">
- <title>Kontrolowanie transakcjami dla zachowania spójności</title>
- <programlisting language="php"><![CDATA[
- // Ręczne rozpoczęcie transakcji
- $db->beginTransaction();
- try {
- // Próba wywołania jednego bądź wielu zapytań:
- $db->query(...);
- $db->query(...);
- $db->query(...);
- // Jeśli wszystkie odniosły sukces - zapisanie transakcji, dzięki czemu wszystkie rezultaty
- // zostaną zapisane za jednym razem.
- $db->commit();
- } catch (Exception $e) {
- // Jeśli któreś z zapytań zakończyło się niepowodzeniem i został wyrzucony wyjątek, należy
- // cofnąć całą transakcję odwracając zmiany w niej dokonane (nawet te które zakończyły się
- // sukcesem). Przez to albo wszystkie zmiany zostają zapisane albo żadna.
- $db->rollBack();
- echo $e->getMessage();
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.adapter.list-describe">
- <title>Uzyskiwanie listy i opisu tabel</title>
- <para>
- Metoda <methodname>listTables()</methodname> zwraca tablicę łańcuchów znakowych,
- zawierającą wszystkie tabele w bieżącej bazie danych.
- </para>
- <para>
- Metoda <methodname>describeTable()</methodname> zwraca tablicę asocjacyjną metadanych
- tabeli. Jako argument należy podać nazwę tabeli.
- Drugi argument jest opcjonalny - wskazuje
- nazwę schematu w którym tabela się znajduje.
- </para>
- <para>
- Kluczami zwracanej tablicy asocjacyjnej są nazwy kolumn tabeli. Wartość przy każdej
- kolumnie to następna tablica asocjacyjna z następującymi kluczami i wartościami:
- </para>
- <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
- <title>Metadane zwracane przez describeTable()</title>
- <tgroup cols="3" align="left" colsep="1" rowsep="1">
- <thead>
- <row>
- <entry>Klucz</entry>
- <entry>Typ</entry>
- <entry>Opis</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry><constant>SCHEMA_NAME</constant></entry>
- <entry>(string)</entry>
- <entry>Nazwa schematu bazy danych, w którym tabela się znajduje.</entry>
- </row>
- <row>
- <entry><constant>TABLE_NAME</constant></entry>
- <entry>(string)</entry>
- <entry>Nazwa tabeli zawierającej daną kolumnę.</entry>
- </row>
- <row>
- <entry><constant>COLUMN_NAME</constant></entry>
- <entry>(string)</entry>
- <entry>Nazwa kolumny.</entry>
- </row>
- <row>
- <entry><constant>COLUMN_POSITION</constant></entry>
- <entry>(integer)</entry>
- <entry>Liczba porządkowa wskazująca na miejsce kolumny w tabeli.</entry>
- </row>
- <row>
- <entry><constant>DATA_TYPE</constant></entry>
- <entry>(string)</entry>
- <entry>Nazwa typu danych dozwolonych w kolumnie.</entry>
- </row>
- <row>
- <entry><constant>DEFAULT</constant></entry>
- <entry>(string)</entry>
- <entry>Domyślna wartość kolumny (jeśli istnieje).</entry>
- </row>
- <row>
- <entry><constant>NULLABLE</constant></entry>
- <entry>(boolean)</entry>
- <entry>
- <constant>TRUE</constant> jeśli columna dopuszcza wartości
- <acronym>SQL</acronym>
- <constant>NULL</constant>, <constant>FALSE</constant>
- jeśli kolumna zawiera
- ograniczenie <constant>NOT</constant> <constant>NULL</constant>.
- </entry>
- </row>
- <row>
- <entry><constant>LENGTH</constant></entry>
- <entry>(integer)</entry>
- <entry>
- Dopuszczalny rozmiar kolumny, w formie zgłoszonej przez serwer
- bazy danych.
- </entry>
- </row>
- <row>
- <entry><constant>SCALE</constant></entry>
- <entry>(integer)</entry>
- <entry>
- Skala typów <acronym>SQL</acronym> NUMERIC lub
- <constant>DECIMAL</constant>.
- </entry>
- </row>
- <row>
- <entry><constant>PRECISION</constant></entry>
- <entry>(integer)</entry>
- <entry>
- Precyzja typów <acronym>SQL</acronym> NUMERIC
- lub <constant>DECIMAL</constant>.
- </entry>
- </row>
- <row>
- <entry><constant>UNSIGNED</constant></entry>
- <entry>(boolean)</entry>
- <entry>
- <constant>TRUE</constant> jeśli typ danych liczbowych ma klauzulę
- <constant>UNSIGNED</constant>.
- </entry>
- </row>
- <row>
- <entry><constant>PRIMARY</constant></entry>
- <entry>(boolean)</entry>
- <entry>
- <constant>TRUE</constant> jeśli kolumna jest częścią
- klucza pierwotnego tabeli.
- </entry>
- </row>
- <row>
- <entry><constant>PRIMARY_POSITION</constant></entry>
- <entry>(integer)</entry>
- <entry>
- Liczba porządkowa (min. 1) oznaczająca pozycję
- kolumny w kluczu pierwotnym.
- </entry>
- </row>
- <row>
- <entry><constant>IDENTITY</constant></entry>
- <entry>(boolean)</entry>
- <entry>
- <constant>TRUE</constant> jeśli kolumna korzysta
- z wartości automatycznie generowanych.
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <note>
- <title>Pole metadanych IDENTITY w różnych systemach zarządzania bazą danych</title>
- <para>
- Pole metadanych IDENTITY zostało wybrane jako ogólny
- termin określający relację do klucza tabeli. Może być znany
- pod następującymi nazwami:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <constant>IDENTITY</constant> - DB2, MSSQL
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>AUTO_INCREMENT</constant> - MySQL
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>SERIAL</constant> - PostgreSQL
- </para>
- </listitem>
- <listitem>
- <para>
- <constant>SEQUENCE</constant> - Oracle
- </para>
- </listitem>
- </itemizedlist>
- </note>
- <para>
- Jeśli w bazie danych nie istnieje tabela i schemat o podanych nazwach to
- <methodname>describeTable()</methodname> zwraca pustą tablicę.
- </para>
- </sect2>
- <sect2 id="zend.db.adapter.closing">
- <title>Zamykanie połączenia</title>
- <para>
- Najczęściej nie ma potrzeby zamykać połączenia z bazą danych. <acronym>PHP</acronym>
- automatycznie czyści wszystkie zasoby pod koniec działania. Rozszerzenia bazy danych są
- zaprojektowane w taki sposób aby połączenie zostało zamknięte w momencie usunięcia
- referencji do obiektu zasobu.
- </para>
- <para>
- Jednak w przypadku skryptu <acronym>PHP</acronym>, którego czas wykonania jest znaczący,
- który inicjuje wiele połączeń z bazą danych, może zajść potrzeba
- ręcznego zamknięcia połączenia aby ograniczyć wykorzystanie
- zasobów serwera bazy danych. Aby wymusić zamknięcie połączenia
- z bazą danych należy użyć metody adaptera <methodname>closeConnection()</methodname>.
- </para>
- <para>
- Od wersji 1.7.2 istnieje możliwość sprawdzenia czy w obecnej chwili
- połączenie z serwerem bazy danych występuje za pomocą metody
- <methodname>isConnected()</methodname>.
- Jej rezultat oznacza czy zasób połączenia został ustanowiony i nie został zamknięty.
- Ta metoda nie jest zdolna sprawdzić zamknięcia połączenia od strony
- serwera bazy danych.
- Dzięki użyciu jej w wewnętrznych metodach zamykających połączenie
- można dokonywać wielokrotnego zamknięcia połączenia bez ryzyka wystąpienia błędów.
- Przed wersją 1.7.2 było to możliwe jedynie w
- przypadku adapterów <acronym>PDO</acronym>.
- </para>
- <example id="zend.db.adapter.closing.example">
- <title>Zamknięcie połączenia z bazą danych</title>
- <programlisting language="php"><![CDATA[
- $db->closeConnection();
- ]]></programlisting>
- </example>
- <note>
- <title>Czy Zend_Db wspiera połączenia trwałe (Persistent Connections)?</title>
- <para>
- Tak, trwałe połączenia są wspierane poprzez flagę <property>persistent</property>
- ustawioną na wartość <constant>TRUE</constant> w konfiguracji
- adaptera <classname>Zend_Db</classname> (a nie sterownika bazy danych).
- </para>
- <example id="zend.db.adapter.connecting.persistence.example">
- <title>Użycie flagi stałego połączenia z adapterem Oracle</title>
- <programlisting language="php"><![CDATA[
- $db = Zend_Db::factory('Oracle', array(
- 'host' => '127.0.0.1',
- 'username' => 'webuser',
- 'password' => 'xxxxxxxx',
- 'dbname' => 'test',
- 'persistent' => true
- ));
- ]]></programlisting>
- </example>
- <para>
- Należy zwrócić uwagę, że używanie połączeń stałych może zwiększyć ilość
- nieużywanych połączeń na serwerze bazy danych. Przez to, korzyści
- w wydajności (wynikające z wykluczenia potrzeby nawiązywania połączenia
- przy każdym żądaniu) mogą zostać skutecznie przeważone przez problemy
- spowodowane przez tą technikę.
- </para>
- <para>
- Połączenia z bazą danych mają stany. Oznacza to, że pewne obiekty na serwerze
- bazy danych istnieją w kontekście sesji. Chodzi o blokady, zmienne użytkownika,
- tabele tymczasowe, informacje o ostatnio wykonanym zapytaniu - takie jak
- ilość pobranych wierszy, ostatnia wygenerowana wartość identyfikatora. W
- przypadku użycia połączeń stałych istnieje ryzyko, że aplikacja uzyska
- dostęp do niepoprawnych bądź zastrzeżonych danych, które zostały utworzone
- podczas poprzedniego żądania.
- </para>
- <para>
- W obecnym stanie jedynie adaptery Oracle, DB2 oraz <acronym>PDO</acronym>
- (zgodnie z dokumentacją <acronym>PHP</acronym>) wspierają połączenia stałe
- w <classname>Zend_Db</classname>.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.db.adapter.other-statements">
- <title>Wykonywanie innych poleceń na bazie danych</title>
- <para>
- Podczas tworzenia kodu może zajść potrzeba uzyskania dostępu bezpośrednio do
- obiektu połączenia tak jak udostępnia to używane rozszerzenie bazy danych
- <acronym>PHP</acronym>. Niektóre rozszerzenia mogą oferować funkcje nieodzwierciedlone
- w metodach klasy <classname>Zend_Db_Adapter_Abstract</classname>.
- </para>
- <para>
- Wszystkie polecenia <acronym>SQL</acronym> w <classname>Zend_Db</classname>
- są wywoływane poprzez instrukcje preparowane (prepared statement). Jednak niektóre
- funkcje bazy danych są z nimi niekompatybilne. Polecenia <acronym>DDL</acronym> takie
- jak CREATE czy ALTER nie mogą być wywoływane w ten sposób w MySQL. Dodatkowo polecenia
- <acronym>SQL</acronym> nie korzystają z
- <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">cache'u zapytań
- MySQL (MySQL Query Cache)</ulink> dla wersji wcześniejszej niż MySQL 5.1.17.
- </para>
- <para>
- Większość rozszerzeń baz danych <acronym>PHP</acronym> umożliwia wywoływanie poleceń
- <acronym>SQL</acronym> bez preparowania. W przypadku <acronym>PDO</acronym> jest to
- możliwe poprzez metodę <methodname>exec()</methodname>. Aby uzyskać dostęp do obiektu
- połączenia odpowiedniego rozszerzenia <acronym>PHP</acronym> należy wywołać metodę
- <methodname>getConnection()</methodname>.
- </para>
- <example id="zend.db.adapter.other-statements.example">
- <title>Wywołanie polecenia niepreparowanego dla adaptera PDO</title>
- <programlisting language="php"><![CDATA[
- $result = $db->getConnection()->exec('DROP TABLE bugs');
- ]]></programlisting>
- </example>
- <para>
- W podobny sposób można korzystać z innych metod szczególnych dla konkretnego
- rozszerzenia <acronym>PHP</acronym>. Należy jednak mieć w pamięci, iż w ten
- sposób ogranicza się tworzoną aplikację do współpracy z interfejsem oferowanym
- jedynie przez konkretne rozszerzenie konkretnej bazy danych.
- </para>
- <para>
- W przyszłych wersjach <classname>Zend_Db</classname> planowane jest umieszczanie
- dodatkowych metod służących do obejmowania funkcjonalności wspólnych dla wielu
- rozszerzeń baz danych <acronym>PHP</acronym> ale wsteczna kompatybilność zostanie
- zachowana.
- </para>
- </sect2>
- <sect2 id="zend.db.adapter.server-version">
- <title>Pobranie wersji serwera</title>
- <para>
- Począwszy od wersji 1.7.2 można pobrać wersję serwera bazy danych w formie podobnej do
- numeru wersji <acronym>PHP</acronym> tak aby można było skorzystać z funkcji
- <methodname>version_compare()</methodname>. Jeśli taka informacja nie jest dostępna
- to zostanie zwrócona wartość <constant>NULL</constant>.
- </para>
- <example id="zend.db.adapter.server-version.example">
- <title>Weryfikacja wersji serwera przed wywołaniem zapytania</title>
- <programlisting language="php"><![CDATA[
- $version = $db->getServerVersion();
- if (!is_null($version)) {
- if (version_compare($version, '5.0.0', '>=')) {
- // wykonanie zapytania
- } else {
- // wykonanie innego zapytania
- }
- } else {
- // wersja serwera niedostępna
- }
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.adapter.adapter-notes">
- <title>Informacje o konkretnych adapterach</title>
- <para>
- Ten akapit wymienia różnice pomiędzy klasami adapterów, z istnienia których
- należy sobie zdawać sprawę.
- </para>
- <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
- <title>IBM DB2</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy 'Db2'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzenia <acronym>PHP</acronym> ibm_db2.
- </para>
- </listitem>
- <listitem>
- <para>
- IBM DB2 wspiera sekwencje oraz klucze automatycznie zwiększające.
- Przez to argumenty dla <methodname>lastInsertId()</methodname> są
- opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
- wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
- podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
- o nazwie zgodnej z konwencją
- '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.mysqli">
- <title>MySQLi</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy 'Mysqli'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzenia <acronym>PHP</acronym> mysqli.
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
- ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
- automatycznego. Metoda <methodname>lastSequenceId()</methodname>
- zwraca <constant>NULL</constant>.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.oracle">
- <title>Oracle</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy 'Oracle'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzenia <acronym>PHP</acronym> oci8.
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
- sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
- <methodname>lastSequenceId()</methodname>.
- </para>
- </listitem>
- <listitem>
- <para>
- Rozszerzenie Oracle nie wspiera parametrów pozycyjnych. Należy
- używać nazwanych parametrów.
- </para>
- </listitem>
- <listitem>
- <para>
- Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
- zaimplementowana w tym adapterze. Aby użyć tej opcji z Oracle zalecane
- jest korzystanie z adaptera <acronym>PDO</acronym> OCI.
- </para>
- </listitem>
- <listitem>
- <para>
- Domyślnie pola LOB są zwracane jako obiekty OCI-Lob. Można ustawić
- pobieranie ich w formie łańcuchów znakowych dla wszystkich żądań
- poprzez opcję sterownika '<property>lob_as_string</property>'. Aby
- jednorazowo pobrać obiekt Lob jako string należy użyć metody
- <methodname>setLobAsString(boolean)</methodname> na adapterze lub
- na obiekcie zapytania.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.sqlsrv">
- <title>Microsoft SQL Server</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy 'Sqlsrv'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzenia <acronym>PHP</acronym> sqlsrv.
- </para>
- </listitem>
- <listitem>
- <para>
- Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
- <methodname>lastInsertId()</methodname> ignoruje argument określający
- klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
- klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
- ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname>
- zwraca <constant>NULL</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Db_Adapter_Sqlsrv</classname> ustawia opcję
- <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
- z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
- zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
- ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu
- Microsoftu - nawiasów kwadratowych.
- </para>
- </listitem>
- <listitem>
- <para>
- Jednym z kluczy podawanych do tablicy opcji może być
- <property>driver_options</property>
- dzięki czemu można skorzystać z wartości podanych w dokumentacji
- <acronym>SQL</acronym> Server
- <ulink url="http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx">
- http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx</ulink>.
- </para>
- </listitem>
- <listitem>
- <para>
- Dzięki metodzie <methodname>setTransactionIsolationLevel()</methodname>
- można ustawić poziom izolacji transakcji dla bieżącego połączenia.
- Rozpoznawane wartości
- to <constant>SQLSRV_TXN_READ_UNCOMMITTED</constant>,
- <constant>SQLSRV_TXN_READ_COMMITTED</constant>,
- <constant>SQLSRV_TXN_REPEATABLE_READ</constant>,
- <constant>SQLSRV_TXN_SNAPSHOT</constant> or
- <constant>SQLSRV_TXN_SERIALIZABLE</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- Począwszy od Zend Framework 1.9 minimalną wspieraną wersją rozszerzenia
- <acronym>PHP</acronym> Microsoft <acronym>SQL</acronym> Server jest
- 1.0.1924.0. a dla <acronym>MSSQL</acronym> Server Native
- Client - wersja 9.00.3042.00.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
- <title>PDO dla IBM DB2 oraz Informix Dynamic Server (IDS)</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Ibm</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_ibm.
- </para>
- </listitem>
- <listitem>
- <para>
- Należy używać wersji 1.2.2 lub wyższej rozszerzenia PDO_IBM. Zaleca się
- uaktualnienie wcześniejszych wersji poprzez <acronym>PECL</acronym>.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
- <title>PDO Microsoft SQL Server</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Mssql</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_dblib.
- </para>
- </listitem>
- <listitem>
- <para>
- Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
- <methodname>lastInsertId()</methodname> ignoruje argument określający
- klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
- klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
- ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname>
- zwraca <constant>NULL</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- W przypadku pracy z łańcuchami znaków unicode zakodowanych w sposób inny
- niż UCS-2 (czyli również w formie UTF-8), może zajść potrzeba dokonania
- konwersji w kodzie aplikacji lub przechowywania
- danych w kolumnach binarnych.
- Aby uzyskać więcej informacji można skorzystać z
- <ulink url="http://support.microsoft.com/kb/232580">Microsoft's Knowledge
- Base</ulink>.
- </para>
- </listitem>
- <listitem>
- <para>
- <classname>Zend_Db_Adapter_Pdo_Mssql</classname> ustawia opcję
- <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
- z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
- zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
- ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu
- Microsoftu - nawiasów kwadratowych.
- </para>
- </listitem>
- <listitem>
- <para>
- Adapter rozpoznaje klucz <property>pdoType</property> w tablicy opcji. Jego
- wartość może wynosić "mssql" (domyślnie), "dblib", "freetds", lub "sybase".
- To wpływa na prefiks <acronym>DSN</acronym> używany przez
- adapter do utworzenia łańcucha połączenia.
- Wartości "freetds" oraz "sybase" powodują utworzenie prefiksu
- "sybase:" używanego przez biblioteki
- <ulink url="http://www.freetds.org/">FreeTDS</ulink>.
- Należy zapoznać się z informacjami dotyczącymi prefiksów
- <acronym>DSN</acronym>
- używanymi przez ten sterownik pod adresem
- <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
- http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
- <title>PDO MySQL</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Mysql</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_mysql.
- </para>
- </listitem>
- <listitem>
- <para>
- MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
- ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
- automatycznego. Metoda <methodname>lastSequenceId()</methodname>
- zwraca <constant>NULL</constant>.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
- <title>PDO Oracle</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Oci</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_oci.
- </para>
- </listitem>
- <listitem>
- <para>
- Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
- sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
- <methodname>lastSequenceId()</methodname>.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
- <title>PDO PostgreSQL</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Pgsql</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_pgsql.
- </para>
- </listitem>
- <listitem>
- <para>
- PostgreSQL wspiera sekwencje oraz klucze automatyczne. Przez to
- podawanie argumentów w <methodname>lastInsertId()</methodname> jest
- opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
- wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
- podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
- o nazwie zgodnej z konwencją
- '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
- <title>PDO SQLite</title>
- <itemizedlist>
- <listitem>
- <para>
- Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname>
- należy użyć nazwy '<classname>Pdo_Sqlite</classname>'.
- </para>
- </listitem>
- <listitem>
- <para>
- Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_sqlite.
- </para>
- </listitem>
- <listitem>
- <para>
- SQLite nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
- ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
- automatycznego. Metoda <methodname>lastSequenceId()</methodname>
- zwraca <constant>NULL</constant>.
- </para>
- </listitem>
- <listitem>
- <para>
- Aby połączyć się z bazą danych SQLite2 należy podać
- <command>'sqlite2' => true</command> jako jeden z elementów
- tablicy parametrów podczas tworzenia instancji adaptera
- <classname>Pdo_Sqlite</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- Aby połączyć się z bazą danych SQLite rezydującą w pamięci
- należy podać <command>'dbname' => ':memory:'</command> jako
- jeden z elementów tablicy parametrów podczas tworzenia instancji adaptera
- <classname>Pdo_Sqlite</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- Starsze wersje sterownika <acronym>PHP</acronym> SQLite nie wspierają
- poleceń PRAGMA niezbędnych dla zachowania krótkich nazw kolumn w
- wynikach zapytania. W przypadku wystąpienia problemów z zapytaniami JOIN
- polegających na zwracaniu wyników z nazwami kolumn w postaci
- "tabela.kolumna" zaleca się aktualizację <acronym>PHP</acronym> do
- najnowszej wersji.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.adapter.adapter-notes.firebird">
- <title>Firebird/Interbase</title>
- <itemizedlist>
- <listitem>
- <para>
- Ten adapter używa rozszerzenia <acronym>PHP</acronym> php_interbase.
- </para>
- </listitem>
- <listitem>
- <para>
- Firebird/Interbase nie wspiera kluczy automatycznych więc należy podać nazwę
- sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
- <methodname>lastSequenceId()</methodname>.
- </para>
- </listitem>
- <listitem>
- <para>
- Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
- zaimplementowana w tym adapterze. Identyfikatory bez znaków ograniczających
- są zwracane w postaci wielkich liter.
- </para>
- </listitem>
- <listitem>
- <para>
- Nazwa adaptera to <classname>ZendX_Db_Adapter_Firebird</classname>.
- </para>
- <para>
- Należy pamiętać o użyciu parametru adapterNamespace z wartością
- <classname>ZendX_Db_Adapter</classname>.
- </para>
- <para>
- Zaleca się aktualizację pliku <filename>gds32.dll</filename> (lub
- odpowiednika wersji linux) dostarczanym z <acronym>PHP</acronym> do wersji odpowiadającej
- serwerowi bazy danych. Dla Firebird odpowiednikiem
- <filename>gds32.dll</filename> jest
- <filename>fbclient.dll</filename>.
- </para>
- <para>
- Domyślnie wszystkie identyfikatory (nazwy tabel, kolumn) są zwracane
- wielkimi literami.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|