|
|
@@ -0,0 +1,2287 @@
|
|
|
+<?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:
|
|
|
+-->
|