Spis treści
Zend_Db_Adapter
jest uniwersalnym interfejsem dostępu
do baz danych dla Zend Framework. Bazuje on na PDO. Używając interfejsu
Zend_Db_Adapter
możesz połączyć się z dowolnym wspieranym
systemem bazodanowym używając tego samego API. Wspierane systemy to
między innymi Microsoft SQL Server, MySQL, PostgreSQL, SQLite, i inne.
Aby utworzyć instancję interfejsu Zend_Db_Adapter
dla
określonego systemu bazodanowego, musisz wywołać metodę Zend_Db::factory()
przekazując jej nazwę systemu bazodanowego oraz tablicę parametrów potrzebnych
do połączenia. Na przykład, aby połączyć się z bazą MySQL nazwaną "camelot"
znajdującą się pod adresem lokalnym, jako użytkownik "malory" możesz zrobić tak:
<?php require_once 'Zend/Db.php'; $params = array ('host' => '127.0.0.1', 'username' => 'malory', 'password' => '******', 'dbname' => 'camelot'); $db = Zend_Db::factory('PDO_MYSQL', $params); ?>
Podobnie, aby połączyć się z bazą SQLite nazwaną "camelot.sq3":
<?php require_once 'Zend/Db.php'; $params = array ('dbname' => 'camelot.sq3'); $db = Zend_Db::factory('PDO_SQLITE', $params); ?>
Podobnie, aby połączyć się z bazą danych SQLite2 o nazwie "camelot.sq2": Dla bazy sqlite opartej na pamięci nie określaj prefiksu dsn i użyj bazy danych o nazwie ":memory:".
<?php require_once 'Zend/Db.php'; $params = array ('dbname' => 'camelot.sq2', 'dsnprefix' => 'sqlite2'); $db = Zend_Db::factory('PDO_SQLITE', $params); ?>
W każdym z tych przypadków będziesz mógł używać takiego samego API aby tworzyć zapytania do bazy.
Powinieneś zawsze cytować wartości, które będą użyte w wyrażeniu SQL;
zapobiega to atakom SQL Injection. Zend_Db_Adapter
zapewnia
dwie metody (poprzez obiekt PDO) aby pomóc Ci manualnie cytować wartości.
Pierwsza z nich to metoda quote()
. Zacytuje ona wartość
skalarną odpowiednio dla twojego adaptera bazy danych; jeśli spróbujesz
cytować tablicę, metoda zwróci łańcuch znaków zawierający wartości
elementów tablicy oddzielone przecinkami. Każda wartość zostanie
odpowiednio zacytowana. (Jest to użyteczne dla funkcji przyjmujących
parametr w postaci listy).
<?php // tworzymy obiekt $db, zakładając, że adapter to Mysql // cytujemy łańcuch znaków $value = $db->quote('St John"s Wort'); // $value ma teraz wartość '"St John\"s Wort"' (zwróć uwagę na otaczające ją cudzysłowy) // cytujemy tablicę $value = $db->quote(array('a', 'b', 'c'); // $value ma teraz wartość '"a", "b", "c"' (elementy tablicy oddzielone przecinkami) ?>
Druga metoda to quoteInto()
. Przekazujesz do niej podstawowy
łańcuch znaków ze znacznikiem w postaci znaku zapytania, a następnie
jedną wartość skalarną lub tablicę która ma być wstawiona. Jest to
użyteczne przy tworzeniu zapytań i warunków po kolei. Wartości
skalarne i tablice działają tak samo jak w metodzie quote()
.
<?php // tworzymy obiekt $db, zakładając, że adapter to Mysql // cytujemy łańcuch znaków dla warunku WHERE $where = $db->quoteInto('id = ?', 1); // $where ma teraz wartość 'id = "1"' (zwróć uwagę na otaczające ją cudzysłowy) // cytujemy tablicę dla warunku WHERE $where = $db->quoteInto('id IN(?)', array(1, 2, 3)); // $where ma teraz wartość 'id IN("1", "2", "3")' (elementy tablicy oddzielone przecinkami) ?>
Gdy posiadasz instancję Zend_Db_Adapter
, możesz wykonywać
zapytania bezpośrednio jako SQL. Zend_Db_Adapter
przekazuje
te zapytania do obiektu PDO, który je przygotowuje i wykonuje, a następnie
zwraca Ci obiekt PDOStatement abyś mógł manipulować danymi wynikowymi
(jeśli jekieś są).
<?php // tworzymy obiekt $db, a następnie wykonujemy // odpowiednio zacytowane zapytanie SQL. $sql = $db->quoteInto( 'SELECT * FROM example WHERE date > ?', '2006-01-01' ); $result = $db->query($sql); // używamy PDOStatement aby pobrać wszystkie wiersze w postaci tablicy $rows = $result->fetchAll(); ?>
Możesz dołączać dane do zapytania automatycznie. Oznacza to, że możesz użyć dowolną ilość nazwanych znaczników w zapytaniu, a następnie przekazać tablicę danych które odpowiadają tym znacznikom. Odpowiadające wartości są automtycznie cytowane, lepiej zabezpieczając przed atakami SQL injection.
<?php // tworzymy obiekt $db, a następnie wykonujemy zapytanie // tym razem używając podmieniania znaczników $result = $db->query( 'SELECT * FROM example WHERE date > :placeholder', array('placeholder' => '2006-01-01') ); // używamy PDOStatement aby pobrać wszystkie wiersze w postaci tablicy $rows = $result->fetchAll(); ?>
Opcjonalnie możesz przygotować i dołączyć dane do zapytań SQL ręcznie.
Aby to zrobić użyj metody prepare()
aby otrzymać
przygotowane zapytanie PDOStatement
, przy którym możesz
bezpośrednio manipulować.
<?php // tworzymy obiekt $db, a następnie wykonujemy zapytanie // tym razem przygotowujemy PDOStatement do ręcznego dołączania. $stmt = $db->prepare('SELECT * FROM example WHERE date > :placeholder'); $stmt->bindValue('placeholder', '2006-01-01'); $stmt->execute(); // używamy PDOStatement aby pobrać wszystkie wiersze w postaci tablicy $rows = $stmt->fetchAll(); ?>
Domyślnie, PDO (a więc i Zend_Db_Adapter
) działają w trybie
"auto-commit". Oznacza to, że wszystkie zapytania są realizowane natychmiast
po ich wykonaniu. Jeśli chcesz je wykonać wewnątrz transakcji, w prosty sposób
wywołak metodę beginTransaction()
, a następnie commit()
aby zrealizować zapytania lub rollBack()
aby je cofnąć.
Zend_Db_Adapter
wraca wtedy do trybu "auto-commit" dopóki
znów nie wywołasz metody beginTransaction()
.
<?php // utwórz obiekt $db, a następnie rozpocznij transakcję $db->beginTransaction(); // próbujemy wykonać zapytanie // jeśli uda się, zatwierdzamy zapytanie; // jeśli nie uda się, cofamy zapytanie. try { $db->query(...); $db->commit(); } catch (Exception $e) { $db->rollBack(); echo $e->getMessage(); } ?>
Dla wygody możesz użyć metody insert()
, która utworzy
zapytanie INSERT oraz dołączy do niego dane, które mają wstawione.
(Dołączone dane zostaną automatycznie zacytowane aby pomóc zapobiegać
atakom SQL injection.)
Zwracana wartość nie jest ostatnio wstawionym
numerem ID, ponieważ tabela nie musi posiadać automatycznie inkrementowanej
kolumny; zwracana wartość jest liczbą wstawionych wierszy (najczęściej 1).
Jeśli chcesz otrzymać wartość ID ostatnio wstawionego rekordu, wywołaj
metodę lastInsertId()
po wstawieniu rekordu.
<?php // // INSERT INTO round_table // (noble_title, first_name, favorite_color) // VALUES ("King", "Arthur", "blue"); // // tworzymy obiekt $db, a następnie... // dane do wstawienia w postaci nazwa_kolumny => wartość $row = array ( 'noble_title' => 'King', 'first_name' => 'Arthur', 'favorite_color' => 'blue', ); // nazwa tabeli do której ma być wstawiony wiersz $table = 'round_table'; // wstawiamy wiersz i pobieramy jego ID $rows_affected = $db->insert($table, $row); $last_insert_id = $db->lastInsertId(); ?>
Dla wygody możesz użyć metody update()
, która utworzy
zapytanie UPDATE oraz dołączy do niego dane które mają być uaktualnione.
(Dołączone dane zostaną automatycznie zacytowane aby pomóc zapobiegać
atakom SQL injection.)
Możesz przekazać do metody opcjonalny warunek WHERE aby określić, które wiersze chcesz zaktualizować.
<?php // // UPDATE round_table // SET favorite_color = "yellow" // WHERE first_name = "Robin"; // // tworzymy obiekt $db, a następnie... // dane do aktualizowania w postaci nazwa_kolumny => wartość $set = array ( 'favorite_color' => 'yellow', ); // nazwa tabeli w której ma być aktualizowany wiersz $table = 'round_table'; // warunek WHERE $where = $db->quoteInto('first_name = ?', 'Robin'); // uaktualniamy tabelę i pobieramy liczbę uaktualnionych wierszy $rows_affected = $db->update($table, $set, $where); ?>
Jeśli masz kilka warunków WHERE, które powinny być dołączone do
zapytania UPDATE, możesz przekazać tablicę tych warunków do metody
update()
. Takie warunki zostaną połączone za pomocą
operatora AND. Łączenie warunków za pomocą operatora OR musi być
przeprowadzone ręcznie:
<?php $set = array('favorite_color' => 'yellow'); // kilka warunków połączonych za pomocą AND $where = array( $db->quoteInto('first_name = ?', $firstName), $db->quoteInto('noble_title = ?', $nobleTitle) ); $count = $db->update('round_table', $set, $where); // kilka warunków połączonych za pomocą OR $firstNameOne = $db->quote($firstNameOne); $firstNameTwo = $db->quote($firstNameTwo); $where = "first_name = $firstNameOne OR first_name = $firstNameTwo"; $count = $db->update('round_table', $set, $where); ?>
Notatka | |
---|---|
Wartości i identyfikatory użyte w warunkach WHERE nie są
automatycznie cytowane. Jeśli masz wartości lub identyfikatory
wymagające cytowania, powinieneś sam to zrobić. Użyj metod
|
Dla wygody możesz użyć metody delete()
, która utworzy
zapytanie DELETE; możesz przekazać do metody opcjonalny warunek
WHERE aby określić, które wiersze chcesz usunąć. (Zauważ, że
warunek WHERE nie jest dołączanym parametrem, więc musisz sam
zacytować jego wartości.)
<?php // // DELETE FROM round_table // WHERE first_name = "Patsy"; // // tworzymy obiekt $db, a następnie... // nazwa tabeli z której usuwamy wiersz $table = 'round_table'; // warunek WHERE $where = $db->quoteInto('first_name = ?', 'Patsy'); // usuwamy wiersz i pobieramy liczbę usuniętych wierszy $rows_affected = $db->delete($table, $where); ?>
Tak jak w metodzie
update()
,
możesz użyć tablicy warunków WHERE dla argumentu $where
metody delete()
.
Notatka | |
---|---|
Wartości i identyfikatory użyte w warunkach WHERE nie są
automatycznie cytowane. Jeśli masz wartości lub identyfikatory
wymagające cytowania, powinieneś sam to zrobić. Użyj metod
|
Chociaż możesz wykonać zapytanie bezpośrednio za pomocą metody
query()
, często wszystko czego potrzebujesz to wybrać
wiersze i pobrać wyniki. Seria metod fetch*()
robi to
dla ciebie. Do każdej z metod fetch*()
, przekazujesz
zapytanie SQL SELECT; jeśli użyjesz nazwanych znaczników w zapytaniu,
możesz przekazać tablicę wartości, które mają być zacytowane i
zamienione w zapytaniu. Metody fetch*()
to:
fetchAll()
fetchAssoc()
fetchCol()
fetchOne()
fetchPairs()
fetchRow()
<?php // tworzymy obiekt $db, a następnie... // pobieramy wszystkie kolumny wszystkich wierszy jako sekwencyjną tablicę $result = $db->fetchAll( "SELECT * FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // pobieramy wszystkie kolumny wszystkich wierszy jako tablicę // asocjacyjną; pierwsza kolumna jest używana jako klucz tablicy $result = $db->fetchAssoc( "SELECT * FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // pobieramy pierwszą kolumnę wszystkich zwróconych wierszy $result = $db->fetchCol( "SELECT first_name FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // pobieramy tylko pierwszą zwróconą wartość $result = $db->fetchOne( "SELECT COUNT(*) FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // pobieramy serię par klucz-wartość; pierwsza kolumna jest // kluczem tablicy, a druga jest wartością $result = $db->fetchPairs( "SELECT first_name, favorite_color FROM round_table WHERE noble_title = :title", array('title' => 'Sir') ); // pobieramy tylko pierwszy zwrócony wiersz $result = $db->fetchRow( "SELECT * FROM round_table WHERE first_name = :name", array('name' => 'Lancelot') ); ?>