| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- 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łowie.
- </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łowie.
- 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 stałe połączenia (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. "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 php 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:
- -->
|