5.4. Zend_Db_Table

5.4.1. Введение

Zend_Db_Table является модулем Zend Framework для таблиц. Он устанавливает соединение с вашей базой данных посредством Zend_Db_Adapter, исследует структуру таблицы, далее помогает вам в манипулировании и извлечении строк из этой таблицы.

5.4.2. Начало работы

Первое, что нужно сделать -- установить для абстрактного класса Zend_Db_Table адаптер БД по умолчанию. Все экземпляры класса Zend_Db_Table будут использовать этот адаптер по умолчанию, пока вы не укажете другое.

<?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);

// установка адаптера по умолчанию для всех объектов Zend_Db_Table
require_once 'Zend/Db/Table.php';
Zend_Db_Table::setDefaultAdapter($db);
?>
        

Теперь предположим, что вы имеете в своей БД таблицу, которая называется "round_table". Чтобы использовать Zend_Db_Table с этой таблицей, просто унаследуйте класс Zend_Db_Table, чтобы создать дочерний класс под именем RoundTable (обратите внимание, что имя класса копирует имя таблицы). Далее мы можем изучать, манипулировть строками и извлекать результаты из таблицы 'round_table' в БД с помощью этого класса.

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

5.4.3. Имя таблицы и первичные ключи

По умолчанию Zend_Db_Table ожидает, что имя данной таблицы в БД будет таким же, как и имя ее собственного класса (в котором разделение слов ЗаглавнымиБуквами заменено разделением знаками_подчеркивания). Таким образом, класс Zend_Db_Table с именем SomeTableName соответствует SQL таблице с именем 'some_table_name'. Если вы желаете, чтобы ваш класс соответствовал чему-либо иному, чем имя класса в форме со знаком подчеркивания, переопределите свойство $_name, когда описываете свой класс.

<?php
class ClassName extends Zend_Db_Table
{
    // имя таблицы по умолчанию -- 'class_name',
    // но мы хотим установить соответствие с чем-то другим
    protected $_name = 'another_table_name';
}
?>
        

По умолчанию Zend_Db_Table ожидает, что ваша таблица имеет первичный ключ с именем 'id'. (Лучше, если этот столбец является автоинкрементным, но это не обязательно.) Если ваш первичный ключ назван по-другому, вы можете переопределить свойство $_primary, когда описываете свой класс.

<?php
class ClassName extends Zend_Db_Table
{
    // первичный ключ по умолчанию -- 'id',
    // но мы хотим использовать другой
    protected $_primary = 'another_column_name';
}
?>
        

Также вы можете установить их в методе _setup() вашего унаследованного класса -- только убедитесь, что после этого вызывается parent::_setup().

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

5.4.4. Вставка строк

Для того, чтобы вставить новую строку в свою таблицу, просто вызывайте insert() с ассоциативным массивом из пар "имя столбца": "значение". В данные будут автоматически добавлены кавычки; метод возвращает последний добавленный ID. (Обратите внимание на то, что этим он отличается от Zend_Db_Adapter::insert(), который возвращает количество затронутых строк.)

<?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);
?>
        

5.4.5. Обновление строк

Для того, чтобы обновить любое количество строк в своей таблице, вызывайте update() с ассоциативным массивом из пар "имя столбца": "значение для установки", наряду с этим передается условие WHERE для определения, какие строки дожны быть обновлены. Метод обновит таблицу и вернет количество затронутых строк.

В данные для установки будут будут автоматически добавлены кавычки, но это не относится к условию WHERE, поэтому вам нужно самим добавить кавычки с помощью принадлежащего таблице объекта 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);
?>
        

5.4.6. Удаление строк

Для того, чтобы удалить любое количество строк в своей таблице, вызывайте delete() с условием WHERE для определения, какие строки должны быть удалены. Метод будет возвращать количество удаленных строк.

В условие WHERE не добавляются кавычки за вас, поэтому вам нужно самим добавить кавычки с помощью объекта Zend_Db_Adapter таблицы.

<?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);
?>
        

5.4.7. Поиск строк по первичному ключу

Вы можете легко извлекать строки из таблицы, используя значения первичного ключа через метод find(). Этот метод возвращает объект Zend_Db_Table_Row, если вы пытаетесь найти только один ключ, или Zend_Db_Table_Rowset, если вы пытаетесь найти несколько ключей.

<?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));
?>
        

5.4.8. Извлечение одной строки

Несмотря на то, что вы можете использовать метод find() для поиска строк по их первичным ключам, часто вам нужно добавлять различные условия, когда извлекате строки. Zend_Db_Table предоставляет fetchRow() только для этой цели. Вызывайте fetchRow() с условием WHERE (и необязательно условием ORDER), и Zend_Db_Table вернет Zend_Db_Table_Row, который будет с первой строкой, удовлетворяющей вашим условиям.

Заметьте, что в условие WHERE не добавляются кавычки за вас, поэтому вам нужно самим добавить кавычки с помощью объекта Zend_Db_Adapter таблицы.

<?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);
?>
        

5.4.9. Извлечение множества строк

Если вам нужно получить больше одной строки за раз, используйте метод fetchAll(). Как и fetchRow(), он принимает условия WHERE и ORDER, но, кроме этого, принимает еще количество строк и смещение для ограничения количества возвращаемых строк. Метод будет возвращать объект Zend_Db_Table_Rowset с выбранными строками.

Заметьте, что в условие WHERE не добавляются кавычки, поэтому вам нужно самим добавить кавычки с помощью объекта Zend_Db_Adapter таблицы.

<?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);
?>
        

5.4.10. Добавление логики предметной области

Zend_Db_Table дает возможность инкапсулировать свою собственную логику предметной области. Например, вы можете переопределить методы insert() и update() для проверки отправляемых данных или манипуляций с ними перед тем, как они будут отправлены БД.

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

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

Аналогичным образом вы можете добавить свои собственные методы для поиска записей по чему-либо иному, чем первичные ключи.

<?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);
    }
}
?>