Programmer's Reference Guide
| Zend_Db_Table |
Zend_Db_Table_Row
Введение
Zend_Db_Table_Row является классом, содержащим отдельную строку объекта Zend_Db_Table. Когда вы производите запрос через класс таблицы, результат возвращается в виде набора объектов Zend_Db_Table_Row. Вы можете также использовать этот объект для создания новых строк и их добавления в таблицу БД.
Zend_Db_Table_Row является реализацией паттерна » Row Data Gateway.
Извлечение строки
Zend_Db_Table_Abstract предоставляет методы find() и
fetchAll(), которые возвращают объект типа
Zend_Db_Table_Rowset, и метод fetchRow(), возвращающий
объект типа Zend_Db_Table_Row.
Пример #1 Пример извлечения строки
- $bugs = new Bugs();
- $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
Объект Zend_Db_Table_Rowset содержит коллекцию объектов Zend_Db_Table_Row. Для получения более подробной информации читайте Zend_Db_Table_Rowset.
Пример #2 Пример получения строки из набора строк
- $bugs = new Bugs();
- $rowset = $bugs->fetchAll($bugs->select()->where('bug_status = ?', 1));
- $row = $rowset->current();
Чтение значений столбцов из строки
Zend_Db_Table_Row_Abstract предоставляет методы-аксессоры, благодаря которым можно ссылаться на столбцы в строке как на свойства объекта.
Пример #3 Пример чтения столбца из строки
- $bugs = new Bugs();
- $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
- // Вывод значения столбца bug_description
Замечание: Более ранние версии Zend_Db_Table_Row сопоставляли аксессоры столбцов и имена столбцов в БД с использованием преобразования строк, называемым инфлекцией.
Zend_Db_Table_Row в его текущей реализации не использует инфлекцию. Написание аксессоров столбцов должно в точности соответствовать именам столбцов, так, как они представлены в БД.
Получение данных строки в виде массива
Вы можете получать данные строки, используя метод
toArray() объекта строки. Метод возвращает
ассоциативный массив имен столбцов и их значений.
Пример #4 Пример использования метода toArray()
- $bugs = new Bugs();
- $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
- // Получение ассоциативного массива столбцов и их значений из объекта Row
- $rowArray = $row->toArray();
- // Теперь используется как обычный массив
- foreach ($rowArray as $column => $value) {
- echo "Column: $column\n";
- echo "Value: $value\n";
- }
Массив, возвращаемый методом toArray() не может
использоваться для обновления данных в БД. Мы можете изменять
значения в этом массиве так же, как и в любом другом массиве, но
не можете сохранять измененные значения непосредственно из этого
массива в БД.
Извлечение данных из связанных таблиц
Класс Zend_Db_Table_Row_Abstract предоставляет методы для извлечения строк и наборов строк из связанных таблиц. Читайте Связи между таблицами Zend_Db_Table для получения более подробной информации о связях между таблицами.
Редактирование строк в БД
Изменение значений столбцов в строке
Используя аксессоры столбцов, вы можете устанавливать значения отдельных столбцов по аналогии с чтением, т.е. так же, как если бы они были свойствами объекта.
Использование аксессоров столбцов для установки значений
изменяет значения столбцов в данном объекте строки, но
эти изменения еще не фиксируются в БД. Вы можете произвести
фиксацию через метод save().
Пример #5 Пример изменения значения столбца в строке
- $bugs = new Bugs();
- $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
- // Изменение значения одного или более столбцов
- $row->bug_status = 'FIXED';
- // Обновление строки в БД с новыми значениями
- $row->save();
Вставка новой строки
Вы можете создавать новые строки для определенной таблицы с
помощью метода createRow() класса таблицы. Можно
работать с полями этой строки через объектно-ориентированный
интерфейс, но строка не сохраняется в БД до тех пор, пока вы не
вызовете метод save().
Пример #6 Пример создания новой строки таблицы
- $bugs = new Bugs();
- $newRow = $bugs->createRow();
- // Установка значений столбцов
- $newRow->bug_description = '...description...';
- $newRow->bug_status = 'NEW';
- // Вставка новой строки в БД
- $newRow->save();
Опциональный аргумент метода является ассоциативным массивом, через который вы можете заполнить поля новой строки.
Пример #7 Пример заполнения новой строки для таблицы
- 'bug_description' => '...description...',
- 'bug_status' => 'NEW'
- );
- $bugs = new Bugs();
- $newRow = $bugs->createRow($data);
- // вставка новой строки в БД
- $newRow->save();
Замечание: В более ранних релизах Zend_Db_Table метод
createRow()называлсяfetchNew(). Мы рекомендуем использовать новое имя метода, несмотря на то, что старое имя метода по-прежнему работает в целях обеспечения обратной совместимости.
Изменение значений в нескольких столбцах
Zend_Db_Table_Row_Abstract предоставляет метод
setFromArray() для того, чтобы можно было
устанавливать значения нескольких столбцов одновременно,
определив ассоциативный массив имен столбцов и их значений.
Этот метод может быть удобным как при создании новых строк, так
и при обновлении существующих.
Пример #8 Пример использования метода setFromArray() для установки значений в новой строке
- $bugs = new Bugs();
- $newRow = $bugs->createRow();
- // Данные помещаются в ассоциативный массив
- 'bug_description' => '...description...',
- 'bug_status' => 'NEW'
- );
- // Одновременная установка значений всех столбцов
- $newRow->setFromArray($data);
- // Добавление новой строки в БД
- $newRow->save();
Удаление строки
Вы можете использовать метод delete() объекта
строки. Этот метод удаляет из таблицы строки, соответствующие
первичному ключу в объекте строки.
Пример #9 Пример удаления строки
- $bugs = new Bugs();
- $row = $bugs->fetchRow('bug_id = 1');
- // Удаление строки
- $row->delete();
Не нужно вызывать метод save() для фиксации
удаления, оно сразу выполняется в БД.
Сериализация и десериализация строк
Часто бывает удобным сохранять содержимое строки БД для последующего использования. Сериализацией называется действие по преобразованию объекта в форму, удобную для хранения в автономном хранилище (например, в файле). Объекты типа Zend_Db_Table_Row_Abstract доступны для сериализации.
Сериализация объекта строки
Просто используйте функцию PHP serialize() для
получения строки, содержащей представление объекта Row в виде
последовательности байт.
Пример #10 Пример сериализации объекта строки
- $bugs = new Bugs();
- $row = $bugs->fetchRow('bug_id = 1');
- // Преобразование объекта в сериализованную форму
- // Теперь вы можете записать $serializedRow в файл и т.д.
Десериализация данных строки
Используйте функцию unserialize() для
восстановления из строки, содержащей представление объекта в
виде последовательности байт. Эта функция возвращает исходный объект.
Внимание: объект строки возвращается без соединения. Вы можете читать объект Row и его свойства, но не можете изменять значения в строке или выполнять другие методы, требующие соединения с БД (например, запросы к связанным таблицам).
Пример #11 Пример десериализации объекта строки
- // Теперь вы можете использовать свойства объекта, но только для чтения
Замечание: Почему объекты строки десериализуются без соединения?
Сериализованный объект является строкой, которая доступна для чтения всем, кто ею обладает. Это создает угрозу безопасности, которая состоит в том, что в сериализованной строке сохраняются такие параметры, как логин и пароль для соединения с БД, в незашифрованном виде. Для вас может быть нежелательным сохранять такие данные в незащищенном текстовом файле, отправлять его через e-mail или любой другой носитель, который может быть прочитан потенциальным атакующим. Тот, кто прочитает сериализованный объект, не должен иметь возможности использовать его в получении несанкционированного доступа к БД.
Восстановление соединения для объекта строки
Вы можете восстановить соединение для строки, используя метод
setTable(). Аргументом этого метода является объект
типа Zend_Db_Table_Abstract, который создается вами. Создание
объекта таблицы требует действующего соединения с БД, поэтому
при переустановке таблицы объект строки получает доступ к БД.
После этого можно изменять значения в объекте строки и
сохранять изменения в БД.
Пример #12 Пример восстановления соединения для строки
- $bugs = new Bugs();
- // Привязка строки к таблице с действующим соединением БД
- $rowClone->setTable($bugs);
- // Теперь вы можете производить изменения в строке и сохранять их
- $rowClone->bug_status = 'FIXED';
- $rowClone->save();
Расширение класса строки
Zend_Db_Table_Row является используемым по умолчанию классом, который наследует от Zend_Db_Table_Row_Abstract. Вы можете определить свой собственный класс для экземпляров строк путем наследования от Zend_Db_Table_Row_Abstract. Для того, чтобы этот класс использовался для хранения результатов запросов к таблице, укажите его имя в защищенном свойстве $_rowClass класса таблицы или в массиве, передаваемом в качестве аргумента конструктору объекта таблицы.
Пример #13 Указание своего класса строки
- class MyRow extends Zend_Db_Table_Row_Abstract
- {
- // ...кастомизация
- }
- // Укажите свой класс строки в качестве используемого по умолчанию
- // во всех экземплярах класса таблицы
- class Products extends Zend_Db_Table_Abstract
- {
- protected $_name = 'products';
- protected $_rowClass = 'MyRow';
- }
- // Или укажите свой класс строки для использования
- // в конкретном экземпляре класса таблицы
Инициализация строки
Если при создании объекта строки требуется выполнять код,
реализующий логику приложения, то вы можете поместить этот код в
метод init(), который вызывается после того,
как были обработаны все метаданные строки. Рекомендуется
использовать этот способ вместо переопределения метода
__construct, если только не требуется изменять
метаданные программным путем.
Пример #14 Пример использования метода init()
- class MyApplicationRow extends Zend_Db_Table_Row_Abstract
- {
- protected $_role;
- public function init()
- {
- $this->_role = new MyRoleClass();
- }
- }
Определение собственной логики для добавления, обновления и удаления в Zend_Db_Table_Row
Класс строки вызывает защищенные методы _insert(),
_update() и _delete() до выполнения
соответствующих операций INSERT,
UPDATE и DELETE. Вы можете добавлять
собственную логику в эти методы в созданном вами подклассе
строки.
Если нужно выполнение собственной логики в определенной
таблице, и эта логика должна выполняться для каждой операции в
этой таблице, то разумным решением может быть реализация
собственной логики в методах insert(),
update() и delete() вашего класса
таблицы. Тем не менее, иногда может быть необходимым выполнять
собственную логику в классе строки.
Ниже приведены примеры случаев, в которых имеет смысл реализовать свою логику в классе строки вместо класса таблицы:
Пример #15 Пример собственной логики в классе строки
Собственная логика может применяться не во всех случаях операций над определенной таблицей. Вы можете реализовать свою логику в классе строки и создавать экземпляр класса таблицы с указанием этого класса строки в качестве используемого. Иначе в таблице используется класс строки по умолчанию.
Вам нужно, чтобы операции над данными в этой таблице журналировались через объект Zend_Log, но только если в конфигурации приложения включено это поведение.
- class MyLoggingRow extends Zend_Db_Table_Row_Abstract
- {
- protected function _insert()
- {
- $log = Zend_Registry::get('database_log');
- $log->info(Zend_Debug::dump($this->_data,
- "INSERT: $this->_tableClass",
- false)
- );
- }
- }
- // $loggingEnabled - свойство, используемое для примера и зависящее
- // от конфигурации вашего приложения
- if ($loggingEnabled) {
- } else {
- $bugs = new Bugs();
- }
Пример #16 Пример класса строки, журналирующего добавляемые данные для нескольких таблиц
Собственная логика может быть общей для нескольких таблиц. Вместо реализации одной и той же логики в каждом классе таблицы вы можете реализовать код этих действий в классе строки и использовать этот класс строки во всех ваших классах таблиц.
В этом примере журналирующий код одинаков для всех классов таблиц.
- class MyLoggingRow extends Zend_Db_Table_Row_Abstract
- {
- protected function _insert()
- {
- $log = Zend_Registry::get('database_log');
- $log->info(Zend_Debug::dump($this->_data,
- "INSERT: $this->_tableClass",
- false)
- );
- }
- }
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- protected $_rowClass = 'MyLoggingRow';
- }
- class Products extends Zend_Db_Table_Abstract
- {
- protected $_name = 'products';
- protected $_rowClass = 'MyLoggingRow';
- }
Определение инфлекции в Zend_Db_Table_Row
Некоторые разработчики предпочитают, чтобы имя класса таблицы соответствовало имени таблицы в СУРБД с применением преобразования, называемого инфлекцией.
Классы Zend_Db по умолчанию не производят инфлекцию. Читайте Определение инфлекции в Zend_Db_Table для получения информации о причинах такого решения.
Если вы предпочитаете использовать инфлекцию, то должны сами
реализовать преобразование, переопределив метод
_transformColumn() в своем классе строки и
использовать этот класс при произведении запросов через ваш
класс таблицы.
Пример #17 Пример определения инфлекционного преобразования
Это позволяет использовать в аксессорах преобразованный
вариант имени столбца. Класс строки использует метод
_transformColumn() для преобразования имени,
которое используется в качестве "родного" имени столбца в
таблице БД.
- class MyInflectedRow extends Zend_Db_Table_Row_Abstract
- {
- protected function _transformColumn($key)
- {
- $nativeKey = myCustomInflector($key);
- return $nativeKey;
- }
- }
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- protected $_rowClass = 'MyInflectedRow';
- }
- $bugs = new Bugs();
- $row = $bugs->createRow();
- // Используются имена столбцов в формате CamelCase, преобразующая функция
- // изменяет их представление на "родное"
- $row->bugDescription = 'New description';
Реализация функций для произведения инфлекционного преобразования возлагается на разработчика. Zend Framework не предоставляет для этих целей готовых функций.
| Zend_Db_Table |
