Documentation

Zend_Db_Table_Row - Zend_Db

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.

Example #1 Пример извлечения строки

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));

Объект Zend_Db_Table_Rowset содержит коллекцию объектов Zend_Db_Table_Row. Для получения более подробной информации читайте Zend_Db_Table_Rowset.

Example #2 Пример получения строки из набора строк

  1. $bugs = new Bugs();
  2. $rowset = $bugs->fetchAll($bugs->select()->where('bug_status = ?', 1));
  3. $row = $rowset->current();

Чтение значений столбцов из строки

Zend_Db_Table_Row_Abstract предоставляет методы-аксессоры, благодаря которым можно ссылаться на столбцы в строке как на свойства объекта.

Example #3 Пример чтения столбца из строки

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
  3.  
  4. // Вывод значения столбца bug_description
  5. echo $row->bug_description;

Note: Более ранние версии Zend_Db_Table_Row сопоставляли аксессоры столбцов и имена столбцов в БД с использованием преобразования строк, называемым инфлекцией.
Zend_Db_Table_Row в его текущей реализации не использует инфлекцию. Написание аксессоров столбцов должно в точности соответствовать именам столбцов, так, как они представлены в БД.

Получение данных строки в виде массива

Вы можете получать данные строки, используя метод toArray() объекта строки. Метод возвращает ассоциативный массив имен столбцов и их значений.

Example #4 Пример использования метода toArray()

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
  3.  
  4. // Получение ассоциативного массива столбцов и их значений из объекта Row
  5. $rowArray = $row->toArray();
  6.  
  7. // Теперь используется как обычный массив
  8. foreach ($rowArray as $column => $value) {
  9.     echo "Column: $column\n";
  10.     echo "Value:  $value\n";
  11. }

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

Извлечение данных из связанных таблиц

Класс Zend_Db_Table_Row_Abstract предоставляет методы для извлечения строк и наборов строк из связанных таблиц. Читайте Связи между таблицами Zend_Db_Table для получения более подробной информации о связях между таблицами.

Редактирование строк в БД

Изменение значений столбцов в строке

Используя аксессоры столбцов, вы можете устанавливать значения отдельных столбцов по аналогии с чтением, т.е. так же, как если бы они были свойствами объекта.

Использование аксессоров столбцов для установки значений изменяет значения столбцов в данном объекте строки, но эти изменения еще не фиксируются в БД. Вы можете произвести фиксацию через метод save().

Example #5 Пример изменения значения столбца в строке

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
  3.  
  4. // Изменение значения одного или более столбцов
  5. $row->bug_status = 'FIXED';
  6.  
  7. // Обновление строки в БД с новыми значениями
  8. $row->save();

Вставка новой строки

Вы можете создавать новые строки для определенной таблицы с помощью метода createRow() класса таблицы. Можно работать с полями этой строки через объектно-ориентированный интерфейс, но строка не сохраняется в БД до тех пор, пока вы не вызовете метод save().

Example #6 Пример создания новой строки таблицы

  1. $bugs = new Bugs();
  2. $newRow = $bugs->createRow();
  3.  
  4. // Установка значений столбцов
  5. $newRow->bug_description = '...description...';
  6. $newRow->bug_status = 'NEW';
  7.  
  8. // Вставка новой строки в БД
  9. $newRow->save();

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

Example #7 Пример заполнения новой строки для таблицы

  1. $data = array(
  2.     'bug_description' => '...description...',
  3.     'bug_status'      => 'NEW'
  4. );
  5.  
  6. $bugs = new Bugs();
  7. $newRow = $bugs->createRow($data);
  8.  
  9. // вставка новой строки в БД
  10. $newRow->save();

Note: В более ранних релизах Zend_Db_Table метод createRow() назывался fetchNew(). Мы рекомендуем использовать новое имя метода, несмотря на то, что старое имя метода по-прежнему работает в целях обеспечения обратной совместимости.

Изменение значений в нескольких столбцах

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

Example #8 Пример использования метода setFromArray() для установки значений в новой строке

  1. $bugs = new Bugs();
  2. $newRow = $bugs->createRow();
  3.  
  4. // Данные помещаются в ассоциативный массив
  5. $data = array(
  6.     'bug_description' => '...description...',
  7.     'bug_status'      => 'NEW'
  8. );
  9.  
  10. // Одновременная установка значений всех столбцов
  11. $newRow->setFromArray($data);
  12.  
  13. // Добавление новой строки в БД
  14. $newRow->save();

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

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

Example #9 Пример удаления строки

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow('bug_id = 1');
  3.  
  4. // Удаление строки
  5. $row->delete();

Не нужно вызывать метод save() для фиксации удаления, оно сразу выполняется в БД.

Сериализация и десериализация строк

Часто бывает удобным сохранять содержимое строки БД для последующего использования. Сериализацией называется действие по преобразованию объекта в форму, удобную для хранения в автономном хранилище (например, в файле). Объекты типа Zend_Db_Table_Row_Abstract доступны для сериализации.

Сериализация объекта строки

Просто используйте функцию PHP serialize() для получения строки, содержащей представление объекта Row в виде последовательности байт.

Example #10 Пример сериализации объекта строки

  1. $bugs = new Bugs();
  2. $row = $bugs->fetchRow('bug_id = 1');
  3.  
  4. // Преобразование объекта в сериализованную форму
  5. $serializedRow = serialize($row);
  6.  
  7. // Теперь вы можете записать $serializedRow в файл и т.д.

Десериализация данных строки

Используйте функцию unserialize() для восстановления из строки, содержащей представление объекта в виде последовательности байт. Эта функция возвращает исходный объект.

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

Example #11 Пример десериализации объекта строки

  1. $rowClone = unserialize($serializedRow);
  2.  
  3. // Теперь вы можете использовать свойства объекта, но только для чтения
  4. echo $rowClone->bug_description;

Note: Почему объекты строки десериализуются без соединения?
Сериализованный объект является строкой, которая доступна для чтения всем, кто ею обладает. Это создает угрозу безопасности, которая состоит в том, что в сериализованной строке сохраняются такие параметры, как логин и пароль для соединения с БД, в незашифрованном виде. Для вас может быть нежелательным сохранять такие данные в незащищенном текстовом файле, отправлять его через e-mail или любой другой носитель, который может быть прочитан потенциальным атакующим. Тот, кто прочитает сериализованный объект, не должен иметь возможности использовать его в получении несанкционированного доступа к БД.

Восстановление соединения для объекта строки

Вы можете восстановить соединение для строки, используя метод setTable(). Аргументом этого метода является объект типа Zend_Db_Table_Abstract, который создается вами. Создание объекта таблицы требует действующего соединения с БД, поэтому при переустановке таблицы объект строки получает доступ к БД. После этого можно изменять значения в объекте строки и сохранять изменения в БД.

Example #12 Пример восстановления соединения для строки

  1. $rowClone = unserialize($serializedRow);
  2.  
  3. $bugs = new Bugs();
  4.  
  5. // Привязка строки к таблице с действующим соединением БД
  6. $rowClone->setTable($bugs);
  7.  
  8. // Теперь вы можете производить изменения в строке и сохранять их
  9. $rowClone->bug_status = 'FIXED';
  10. $rowClone->save();

Расширение класса строки

Zend_Db_Table_Row является используемым по умолчанию классом, который наследует от Zend_Db_Table_Row_Abstract. Вы можете определить свой собственный класс для экземпляров строк путем наследования от Zend_Db_Table_Row_Abstract. Для того, чтобы этот класс использовался для хранения результатов запросов к таблице, укажите его имя в защищенном свойстве $_rowClass класса таблицы или в массиве, передаваемом в качестве аргумента конструктору объекта таблицы.

Example #13 Указание своего класса строки

  1. class MyRow extends Zend_Db_Table_Row_Abstract
  2. {
  3.     // ...кастомизация
  4. }
  5.  
  6. // Укажите свой класс строки в качестве используемого по умолчанию
  7. // во всех экземплярах класса таблицы
  8. class Products extends Zend_Db_Table_Abstract
  9. {
  10.     protected $_name = 'products';
  11.     protected $_rowClass = 'MyRow';
  12. }
  13.  
  14. // Или укажите свой класс строки для использования
  15. // в конкретном экземпляре класса таблицы
  16. $bugs = new Bugs(array('rowClass' => 'MyRow'));

Инициализация строки

Если при создании объекта строки требуется выполнять код, реализующий логику приложения, то вы можете поместить этот код в метод init(), который вызывается после того, как были обработаны все метаданные строки. Рекомендуется использовать этот способ вместо переопределения метода __construct, если только не требуется изменять метаданные программным путем.

Example #14 Пример использования метода init()

  1. class MyApplicationRow extends Zend_Db_Table_Row_Abstract
  2. {
  3.     protected $_role;
  4.  
  5.     public function init()
  6.     {
  7.         $this->_role = new MyRoleClass();
  8.     }
  9. }

Определение собственной логики для добавления, обновления и удаления в Zend_Db_Table_Row

Класс строки вызывает защищенные методы _insert(), _update() и _delete() до выполнения соответствующих операций INSERT, UPDATE и DELETE. Вы можете добавлять собственную логику в эти методы в созданном вами подклассе строки.

Если нужно выполнение собственной логики в определенной таблице, и эта логика должна выполняться для каждой операции в этой таблице, то разумным решением может быть реализация собственной логики в методах insert(), update() и delete() вашего класса таблицы. Тем не менее, иногда может быть необходимым выполнять собственную логику в классе строки.

Ниже приведены примеры случаев, в которых имеет смысл реализовать свою логику в классе строки вместо класса таблицы:

Example #15 Пример собственной логики в классе строки

Собственная логика может применяться не во всех случаях операций над определенной таблицей. Вы можете реализовать свою логику в классе строки и создавать экземпляр класса таблицы с указанием этого класса строки в качестве используемого. Иначе в таблице используется класс строки по умолчанию.

Вам нужно, чтобы операции над данными в этой таблице журналировались через объект Zend_Log, но только если в конфигурации приложения включено это поведение.

  1. class MyLoggingRow extends Zend_Db_Table_Row_Abstract
  2. {
  3.     protected function _insert()
  4.     {
  5.         $log = Zend_Registry::get('database_log');
  6.         $log->info(Zend_Debug::dump($this->_data,
  7.                                     "INSERT: $this->_tableClass",
  8.                                     false)
  9.                   );
  10.     }
  11. }
  12.  
  13. // $loggingEnabled - свойство, используемое для примера и зависящее
  14. // от конфигурации вашего приложения
  15. if ($loggingEnabled) {
  16.     $bugs = new Bugs(array('rowClass' => 'MyLoggingRow'));
  17. } else {
  18.     $bugs = new Bugs();
  19. }

Example #16 Пример класса строки, журналирующего добавляемые данные для нескольких таблиц

Собственная логика может быть общей для нескольких таблиц. Вместо реализации одной и той же логики в каждом классе таблицы вы можете реализовать код этих действий в классе строки и использовать этот класс строки во всех ваших классах таблиц.

В этом примере журналирующий код одинаков для всех классов таблиц.

  1. class MyLoggingRow extends Zend_Db_Table_Row_Abstract
  2. {
  3.     protected function _insert()
  4.     {
  5.         $log = Zend_Registry::get('database_log');
  6.         $log->info(Zend_Debug::dump($this->_data,
  7.                                     "INSERT: $this->_tableClass",
  8.                                     false)
  9.                   );
  10.     }
  11. }
  12.  
  13. class Bugs extends Zend_Db_Table_Abstract
  14. {
  15.     protected $_name = 'bugs';
  16.     protected $_rowClass = 'MyLoggingRow';
  17. }
  18.  
  19. class Products extends Zend_Db_Table_Abstract
  20. {
  21.     protected $_name = 'products';
  22.     protected $_rowClass = 'MyLoggingRow';
  23. }

Определение инфлекции в Zend_Db_Table_Row

Некоторые разработчики предпочитают, чтобы имя класса таблицы соответствовало имени таблицы в СУРБД с применением преобразования, называемого инфлекцией.

Классы Zend_Db по умолчанию не производят инфлекцию. Читайте Определение инфлекции в Zend_Db_Table для получения информации о причинах такого решения.

Если вы предпочитаете использовать инфлекцию, то должны сами реализовать преобразование, переопределив метод _transformColumn() в своем классе строки и использовать этот класс при произведении запросов через ваш класс таблицы.

Example #17 Пример определения инфлекционного преобразования

Это позволяет использовать в аксессорах преобразованный вариант имени столбца. Класс строки использует метод _transformColumn() для преобразования имени, которое используется в качестве "родного" имени столбца в таблице БД.

  1. class MyInflectedRow extends Zend_Db_Table_Row_Abstract
  2. {
  3.     protected function _transformColumn($key)
  4.     {
  5.         $nativeKey = myCustomInflector($key);
  6.         return $nativeKey;
  7.     }
  8. }
  9.  
  10. class Bugs extends Zend_Db_Table_Abstract
  11. {
  12.     protected $_name = 'bugs';
  13.     protected $_rowClass = 'MyInflectedRow';
  14. }
  15.  
  16. $bugs = new Bugs();
  17. $row = $bugs->createRow();
  18.  
  19. // Используются имена столбцов в формате CamelCase, преобразующая функция
  20. // изменяет их представление на "родное"
  21. $row->bugDescription = 'New description';

Реализация функций для произведения инфлекционного преобразования возлагается на разработчика. Zend Framework не предоставляет для этих целей готовых функций.

Copyright

© 2006-2017 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts