Zend_Db_Select jest narzędziem pomagającym w budowaniu zapytań SQL SELECT w sposób niezależny od rodzaju bazy danych. Oczywiście nie może to być perfekcyjne, ale pomaga w tym, aby zapytania były przenośne pomiędzy różnymi systemami bazodanowymi. Dodatkowo pomaga to w uodpornieniu zapytań na ataki SQL injection.
Najprostszy sposób utworzenia instancji Zend_Db_Select to użycie metody Zend_Db_Adapter::select().
<?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); $select = $db->select(); // $select jest teraz obiektem Zend_Db_Select skonfigurowanym do użycia z adapterem PDO_MYSQL. ?>
Wtedy konstruujesz zapytanie SELECT używając tego obiektu i jego metod, a następnie generujesz łańcuch znaków który przekazujesz spowrotem do obiektu Zend_Db_Adapter w celu wykonania zapytania.
<?php // // SELECT * // FROM round_table // WHERE noble_title = "Sir" // ORDER BY first_name // LIMIT 10 OFFSET 20 // // możesz użyć stylu iteracyjnego... $select->from('round_table', '*'); $select->where('noble_title = ?', 'Sir'); $select->order('first_name'); $select->limit(10,20); // ...lub stylu łańcuchowego: $select->from('round_table', '*') ->where('noble_title = ?', 'Sir') ->order('first_name') ->limit(10,20); // pobieramy dane $sql = $select->__toString(); $result = $db->fetchAll($sql); // alternatywnie, możesz przekazać sam obiekt $select; // Zend_Db_Adapter jest na tyle sprytny aby użyć funkcji __toString() // na obiektach Zend_Db_Select w celu otrzymania treści zapytania. $result = $db->fetchAll($select); ?>
Możesz także użyć parametrów wstawianych w miejsce nazwanych znaczników, zamiast cytowania parametrów po kolei.
<?php // // SELECT * // FROM round_table // WHERE noble_title = "Sir" // ORDER BY first_name // LIMIT 10 OFFSET 20 // $select->from('round_table', '*') ->where('noble_title = :title') ->order('first_name') ->limit(10,20); // pobieramy wyniki używająć parametrów wstawianych w miejsce znaczników $params = array('title' => 'Sir'); $result = $db->fetchAll($select, $params); ?>
Aby wybrać kolumny z określonej tabeli, użyj metody from(), określając tabelę oraz kolumny których potrzebujesz. Możesz użyć aliasów dla tabel oraz kolumn, i możesz używać metody from() tyle razy ile potrzebujesz.
<?php // tworzymy obiekt $db, zakładając, że adapter to Mysql $select = $db->select(); // SELECT a, b, c FROM some_table $select->from('some_table', 'a, b, c'); // równażnie: $select->from('some_table', array('a', 'b', 'c'); // SELECT bar.col FROM foo AS bar $select->from('foo AS bar', 'bar.col'); // SELECT foo.col AS col1, bar.col AS col2 FROM foo, bar $select->from('foo', 'foo.col AS col1'); $select->from('bar', 'bar.col AS col2'); ?>
Aby wybrać kolumny używając złączonych tabel, użyj metody join(). Wpierw określ nazwę złączanej tabeli, następnie wyrażenie łączące, a na końcu kolumny które potrzebujesz dołączyć. Możesz użyć metody join() tyle razy ile potrzebujesz.
<?php // tworzymy obiekt $db, zakładając, że adapter to Mysql $select = $db->select(); // // SELECT foo.*, bar.* // FROM foo // JOIN bar ON foo.id = bar.id // $select->from('foo', '*'); $select->join('bar', 'foo.id = bar.id', '*'); ?>
Obecnie jedynie składnia JOIN jest obsługiwana; nie ma możliwości użycia składni LEFT JOIN, RIGHT JOIN, itp. W przyszłości składnia ta będzie obsługiwana w sposób niezależny dla każdego typu bazy danych.
Aby dodać warunki WHERE, użyj metody where(). Możesz przekazać zwykły łańcuch znaków lub możesz przekazać łańcuch znaków ze znacznikiem w postaci znaku zapytania oraz wartość która ma być zacytowana. (wartość będzie zacytowana za pomocą metody Zend_Db_Adapter::quoteInto).
Kolejne wywołania where() będą łączyć warunki za pomocą AND; jeśli chcesz je złączyć za pomocą OR, użyj metody orWhere().
<?php // tworzymy obiekt $db, a następie odbieramy narzędzie SELECT. $select = $db->select(); // // SELECT * // FROM round_table // WHERE noble_title = "Sir" // AND favorite_color = "yellow" // $select->from('round_table', '*'); $select->where('noble_title = "Sir"'); // osadzona wartość $select->where('favorite_color = ?', 'yellow'); // cytowana wartość // // SELECT * // FROM foo // WHERE bar = "baz" // OR id IN("1", "2", "3") // $select->from('foo', '*'); $select->where('bar = ?', 'baz'); $select->orWhere('id IN(?)', array(1, 2, 3); ?>
Aby grupować wiersze użyj metody group() tyle razy ile potrzebujesz.
<?php // tworzymy obiekt $db, a następie odbieramy narzędzie SELECT. $select = $db->select(); // // SELECT COUNT(id) // FROM foo // GROUP BY bar, baz // $select->from('foo', 'COUNT(id)'); $select->group('bar'); $select->group('baz'); // wywołanie metody group(): $select->group('bar, baz'); // inny sposób wywołania metody group(): $select->group(array('bar', 'baz')); ?>
Aby dodać warunki HAVING dla wybranych wyników użyj metody having(). Ta metoda jest identyczna w użyciu jak metoda where().
Kolejne wywołania having() będą łączyć warunki za pomocą AND; jeśli chcesz je złączyć za pomocą OR, użyj metody orHaving().
<?php // tworzymy obiekt $db, a następie odbieramy narzędzie SELECT. $select = $db->select(); // // SELECT COUNT(id) AS count_id // FROM foo // GROUP BY bar, baz // HAVING count_id > "1" // $select->from('foo', 'COUNT(id) AS count_id'); $select->group('bar, baz'); $select->having('count_id > ?', 1); ?>
Aby sortować dane użyj metody order() tyle razy ile potrzebujesz.
<?php // tworzymy obiekt $db, a następie odbieramy narzędzie SELECT. $select = $db->select(); // // SELECT * FROM round_table // ORDER BY noble_title DESC, first_name ASC // $select->from('round_table', '*'); $select->order('noble_title DESC'); $select->order('first_name'); // wywołanie metody order(): $select->order('noble_title DESC, first_name'); // inny sposób wywołania metody order(): $select->order(array('noble_title DESC', 'first_name')); ?>
Zend_Db_Select oferuje obsługę bazodanowej składni LIMIT. Dla wielu baz danych, np. MySQL czy PostgreSQL, jest to relatywnie proste, ponieważ obsługują one składnię "LIMIT :count [OFFSET :offset]".
Dla innych baz danych, takich jak Microsoft SQL czy Oracle, nie jest to takie proste, ponieważ nie obsługują one składni LIMIT. MS-SQL posiada jedynie składnię TOP, a Oracle wymaga zapytań napisanych w specjalny sposób aby emulować LIMIT. Dzięki temu, że Zend_Db_Select działa wewnętrznie, możemy w locie przepisać zapytanie SELECT aby emulować funkcjonalność LIMIT wyżej wymienionych systemów bazodanowych open-source.
Aby limitować zwracane wyniki na podstawie ilości i offsetu użyj metody limit() podając ilość oraz opcjonalny offset.
<?php // na początek prosty "LIMIT :count" $select = $db->select(); $select->from('foo', '*'); $select->order('id'); $select->limit(10); // // W MySQL/PostgreSQL/SQLite odpowiada to zapytaniu: // // SELECT * FROM foo // ORDER BY id ASC // LIMIT 10 // // A w Microsoft SQL odpowiada to zapytaniu: // // SELECT TOP 10 * FROM FOO // ORDER BY id ASC // // // a teraz bardziej złożony "LIMIT :count OFFSET :offset" $select = $db->select(); $select->from('foo', '*'); $select->order('id'); $select->limit(10, 20); // // W MySQL/PostgreSQL/SQLite odpowiada to zapytaniu: // // SELECT * FROM foo // ORDER BY id ASC // LIMIT 10 OFFSET 20 // // Ale w Microsoft SQL, który nie obsługuje offset, odpowiada to zapytaniu: // // SELECT * FROM ( // SELECT TOP 10 * FROM ( // SELECT TOP 30 * FROM foo ORDER BY id DESC // ) ORDER BY id ASC // ) // // Zend_Db_Adapter automatycznie tłumaczy zapytanie. // ?>
Zend_Db_Select oferuje limitowanie wyników oparte na stronach. Jeśli chcesz pobrać pewną stronę wyników, użyj metody limitPage(); wpierw przekaż numer strony którą potrzebujesz, a nąstępnie ilość wierszy jaka ma się pojawiać na każdej ze stron.
<?php // budujemy podstawowe zapytanie select... $select = $db->select(); $select->from('foo', '*'); $select->order('id'); // ... i limitujemy do strony 3 gdzie każda strona ma 10 wierszy $select->limitPage(3, 10); // // W MySQL/PostgreSQL/SQLite, odpowiada to zapytaniu: // // SELECT * FROM foo // ORDER BY id ASC // LIMIT 10 OFFSET 20 // ?>