9.4. Zend_Db_Table

9.4.1. Wprowadzenie

Zend_Db_Table jest modułem obsługi tabel dla Zend Framework. Łączy się on z bazą danych poprzez Zend_Db_Adapter, sprawdza strukturę tabeli, a następnie pomaga w pobieraniu wierszy z tabeli i w manipulacji nimi.

9.4.2. Pierwsze kroki

Pierwszą rzeczą do zrobienia jest ustawienie domyślnego adaptera bazy danych dla klasy Zend_Db_Table; jeśli później nie określisz innego adaptera, to wszystkie instancje Zend_Db_Table będą używać tego domyślnego adaptera.

<?php
// przygotujmy adapter
require_once 'Zend/Db.php';
$params = array (
    'host'     => '127.0.0.1',
    'username' => 'malory',
    'password' => '******',
    'dbname'   => 'camelot'
);

$db = Zend_Db::factory('PDO_MYSQL', $params);

// ustawmy domyślny adapter dla wszystkich obiektów Zend_Db_Table
require_once 'Zend/Db/Table.php';
Zend_Db_Table::setDefaultAdapter($db);
?>
        

Następnie załóżmy, że masz w swojej bazie tabelę nazwaną "round_table". Aby użyć Zend_Db_Table z tą tabelą po prostu rozszerz klasę Zend_Db_Table aby utworzyć nową klasę nazwaną RoundTable (zauważ jak przekształcamy nazwę tabeli). Wtedy możemy sprawdzać strukturę tabeli, manipulować wierszami i pobierać wiersze z tabeli 'round_table' za pomocą tej klasy.

<?php
class RoundTable extends Zend_Db_Table {}
$table = new RoundTable();
?>
        

9.4.3. Nazwa tabeli oraz klucz podstawowy

Domyślnie Zend_Db_Table oczekuje, że nazwa tabeli w bazie danych będzie taka sama jak nazwa klasy (po konwersji z CamelCaps na underscore_words). Więc klasa Zend_Db_Table rozszerzona do klasy nazwanej JakasNazwaTabeli mapuje tabelę SQL nazwaną 'jakas_nazwa_tabeli'. Jeśli chcesz, by twoja klasa mapowała inną tabelę niż ta z nazwy klasy, nadpisz właściwość $_name gdy definiujesz swoją klasę.

<?php
class ClassName extends Zend_Db_Table
{
    // domyślna nazwa tabeli to 'nazwa_klasy'
    // ale chcemy zmapować ją na inną
    protected $_name = 'inna_nazwa_tabeli';
}
?>
        

Domyślnie Zend_Db_Table oczekuje, że tabela ma klucz podstawowy nazwany 'id'. (Najlepiej gdy jest to kolumna automatycznie inkrementowana, ale nie jest to wymagane.) Jeśli twój klucz podstawowy nazwany jest inaczej, możesz nadpisać właściwość $_primary gdy definiujesz swoją klasę.

<?php
class ClassName extends Zend_Db_Table
{
    // domyślny klucz podstawowy to 'id'
    // ale chcemy użyć czegoś innego
    protected $_primary = 'inna_nazwa_kolumny';
}
?>
        

Alternatywnie możesz ustawić je w metodzie _setup() twojej rozszerzonej klasy; pamiętaj tylko aby wywołać metodę parent::_setup() klasy rozszerzanej.

<?php
class ClassName extends Zend_Db_Table
{
    protected function _setup()
    {
        $this->_name = 'inna_nazwa_tabeli';
        $this->_primary = 'inna_nazwa_kolumny';
        parent::_setup();
    }
}
?>
        

9.4.4. Wstawianie wierszy

Aby dodać nowy wiersz do tabeli, po prostu wywołaj metodę insert() z asocjacyjną tablicą w postaci kolumna:wartość w parametrze. Dane będą automatycznie zacytowane, a zwrócony zostanie ID ostatnio wstawionego wiersza. (Zauważ, że różni się to od metody Zend_Db_Adapter::insert(), w której zwracana jets liczba wstawionych wierszy)

<?php
//
// INSERT INTO round_table
//     (noble_title, first_name, favorite_color)
//     VALUES ("King", "Arthur", "blue")
//

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();

$data = array(
    'noble_title' => 'King',
    'first_name'  => 'Arthur',
    'favorite_color' => 'blue',
)

$id = $table->insert($data);
?>
        

9.4.5. Uaktualnianie wierszy

Aby zaktualizować wiersz w tabeli, wywołaj metodę update() z asocjacyjną tablicą w postaci kolumna:wartość w pierwszym parametrze, oraz z warunkiem WHERE określającym wiersze które mają być zaktualizowane w drugim parametrze. Uaktualni to tabelę a następnie zwróci ilość uaktualnionych wierszy.

Dane do uaktualnienia będą automatycznie zacytowane, ale warunek WHERE nie będzie, więc musisz zacytować go sam za pomocą obiektu Zend_Db_Adapter.

<?php
//
// UPDATE round_table
//     SET favorite_color = "yellow"
//     WHERE first_name = "Robin"
//

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$set = array(
    'favorite_color' => 'yellow',
)

$where = $db->quoteInto('first_name = ?', 'Robin');

$rows_affected = $table->update($set, $where);
?>
        

9.4.6. Usuwanie wierszy

Aby usunąć dowolną ilość wierszy z tabeli, wywołaj metodę delete() z warunkiem WHERE który określa wiersza które mają być usunięte. Funkcja zwróci ilość usuniętych wierszy.

Warunek WHERE nie będzie automatycznie zacytowany, więc powinieneś zrobić to sam używając obiektu Zend_Db_Adapter dla tej tabeli.

<?php
//
// DELETE FROM round_table
//     WHERE first_name = "Patsy"
//

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$where = $db->quoteInto('first_name = ?', 'Patsy');

$rows_affected = $table->delete($where);
?>
        

9.4.7. Wyszukiwanie wierszy na podstawie klucza podstawowego

Możesz wygodnie pobierać wiersze z tabeli na podstawie klucza podstawowego używając metody find(). Metoda zwraca obiekt Zend_Db_Table_Row jeśli przekażesz jako parametr jeden klucz, lub obiekt Zend_Db_Table_Rowset gdy przekażesz jako parametr większą ilość kluczy.

<?php
class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();

// SELECT * FROM round_table WHERE id = "1"
$row = $table->find(1);

// SELECT * FROM round_table WHERE id IN("1", "2", 3")
$rowset = $table->find(array(1, 2, 3));
?>
        

9.4.8. Pobieranie jednego wiersza

O ile możesz łatwo znaleźć wiersz na podstawie klucza podstawowego za pomocą metody find(), to często potrzebujesz dodać różnego rodzaju warunki gdy pobierasz wiersz. Zend_Db_Table zapewnia do tych zastosowań metodę fetchRow(). Wywołaj fetchRow() z warunkiem WHERE w parametrze (oraz z opcjonalnym warunkiem ORDER), a Zend_Db_Table zwróci obiekt Zend_Db_Table_Row zawierający pierwszy rekord spełniający twoje kryteria.

Zauważ, że warunek WHERE nie będzie automatycznie zacytowany, więc powinieneś zrobić to sam używając obiektu Zend_Db_Adapter dla tej tabeli.

<?php
//
// SELECT * FROM round_table
//     WHERE noble_title = "Sir"
//     AND first_name = "Robin"
//     ORDER BY favorite_color
//

class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

$where = $db->quoteInto('noble_title = ?', 'Sir')
       . $db->quoteInto('AND first_name = ?', 'Robin');

$order = 'favorite_color';

$row = $table->fetchRow($where, $order);
?>
        

9.4.9. Pobieranie wielu wierszy

Jeśli chcesz pobrać wiele wierszy na raz, użyj metody fetchAll(). Tak jak metoda fetchRow(), przyjmuje ona parametry określające warunki WHERE oraz ORDER, a także przyjmuje parametry oznaczające ilość rekordów do pobrania oraz offset od ktorego ma zacząć pobieranie Zwróci ona obiekt Zend_Db_Table_Rowset zawierający wskazane wiersze.

Zauważ, że warunek WHERE nie będzie automatycznie zacytowany, więc powinieneś zrobić to sam używając obiektu Zend_Db_Adapter dla tej tabeli.

<?php
class RoundTable extends Zend_Db_Table {}

$table = new RoundTable();
$db = $table->getAdapter();

// SELECT * FROM round_table
//     WHERE noble_title = "Sir"
//     ORDER BY first_name
//     LIMIT 10 OFFSET 20

$where = $db->quoteInto('noble_title = ?', 'Sir');
$order = 'first_name';
$count = 10;
$offset = 20;

$rowset = $table->fetchAll($where, $order, $count, $offset);
?>
        

9.4.10. Dodawanie logiki biznesowej

Jako moduł obsługi tabel, Zend_Db_Table pozwala na dodanie własnej logiki biznesowej. Na przykład możesz nadpisać metody insert() oraz update() aby manipulować danymi lub sprawdzać ich poprawność przed przekazaniem ich do bazy danych.

<?php
class RoundTable extends Zend_Db_Table
{
    public function insert($data)
    {
        // dodajemy aktualny czas
        if (empty($data['created_on'])) {
            $data['created_on'] = time();
        }
        return parent::insert($data);
    }

    public function update($data)
    {
        // dodajemy aktualny czas
        if (empty($data['updated_on'])) {
            $data['updated_on'] = time();
        }
        return parent::update($data);
    }
}
?>
        

Analogicznie możesz dodać własne metody find() aby wyszukiwać rekordów w inny sposób niż za pomocą klucza podstawowego.

<?php
class RoundTable extends Zend_Db_Table
{
    public function findAllWithName($name)
    {
        $db = $this->getAdapter();
        $where = $db->quoteInto("name = ?", $name);
        $order = "first_name";
        return $this->fetchAll($where, $order);
    }
}
?>