Главная / Zend Manual Core
Zend_Db_Table_Row

Zend_Db_Table_Rowset

Введение

Когда вы производите запрос через класс таблицы, используя методы find() или fetchAll(), результат возвращается в объекте типа Zend_Db_Table_Rowset_Abstract. Набор строк (rowset) содержит коллекцию объектов, наследующих от Zend_Db_Table_Row_Abstract. Вы можете производить итерацию по набору строк и работать с отдельными объектами строк, считывая или изменяя данные в строках.

Получение набора строк

Zend_Db_Table_Abstract предоставляет методы find() и fetchAll(), оба они возвращают объект типа Zend_Db_Table_Rowset_Abstract.

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

  1. $bugs   = new Bugs();
  2. $rowset = $bugs->fetchAll("bug_status = 'NEW'");

Получение строк из набора

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

Правильно составленный запрос возвращает нулевое количество строк, если в БД нет строк, соответствующих условиям запроса. Поэтому объект набора строк может содержать нулевое количество объектов строк. Поскольку Zend_Db_Table_Rowset_Abstract реализует инерфейс Countable, то вы можете использовать count() для определения количества строк в наборе строк.

Example #2 Подсчет количества строк в наборе строк

  1. $rowset   = $bugs->fetchAll("bug_status = 'FIXED'");
  2.  
  3. $rowCount = count($rowset);
  4.  
  5. if ($rowCount > 0) {
  6.     echo "found $rowCount rows";
  7. } else {
  8.     echo 'no rows matched the query';
  9. }

Example #3 Чтение одной строки из набора строк

Наиболее простой способ получения доступа к строке из набора состоит в использовании метода current(). Этот способ особенно подходит для тех случаев, когда набор строк содержит только одну строку.

  1. $bugs   = new Bugs();
  2. $rowset = $bugs->fetchAll("bug_id = 1");
  3. $row    = $rowset->current();

Если набор строк содержит нулевое количество строк, то current() вернет значение NULL.

Example #4 >Итерация по набору строк

Объекты, наследующие от Zend_Db_Table_Rowset_Abstract, реализуют интерфейс Iterator. Это значит, что можно производить циклический обход объектов, используя конструкцию foreach(). Каждое значение, получаемое таким образом, является объектом типа Zend_Db_Table_Row_Abstract, который соответствует одной записи в таблице.

  1. $bugs = new Bugs();
  2.  
  3. // извлечение всех записей из таблицы
  4. $rowset = $bugs->fetchAll();
  5.  
  6. foreach ($rowset as $row) {
  7.  
  8.     // выводит 'Zend_Db_Table_Row' или подобное
  9.     echo get_class($row) . "\n";
  10.  
  11.     // чтение столбца в строке
  12.     $status = $row->bug_status;
  13.  
  14.     // изменение столбца в текущей строке
  15.     $row->assigned_to = 'mmouse';
  16.  
  17.     // сохранение изменений в БД
  18.     $row->save();
  19. }

getRow() позволяет извлекать строку из набора строк, используя номер ее позиции, при этом не забывайте, что отсчет позиции начинается с нуля. Первый параметр метода getRow() должен быть целочисленным и используется для передачи позиции строки. Второй необязательный параметр должен иметь булев тип, при передаче значения true итератор перемещается в данную позицию (по умолчанию используется значение false). По умолчанию этот метод возвращает объект Zend_Db_Table_Row. Если запрошенная позиция не существует, то бросается исключение. Ниже приведен пример:

  1. $bugs = new Bugs();
  2.  
  3. // извлечение всех строк из таблицы
  4. $rowset = $bugs->fetchAll();
  5.  
  6. // извлечение девятой строки:
  7. $row9->getRow(8);
  8.  
  9. // и ее применение:
  10. $row9->assigned_to = 'mmouse';
  11. $row9->save();

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

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

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

Example #5 Использование toArray()

  1. $bugs   = new Bugs();
  2. $rowset = $bugs->fetchAll();
  3.  
  4. $rowsetArray = $rowset->toArray();
  5.  
  6. $rowCount = 1;
  7. foreach ($rowsetArray as $rowArray) {
  8.     echo "row #$rowCount:\n";
  9.     foreach ($rowArray as $column => $value) {
  10.         echo "\t$column => $value\n";
  11.     }
  12.     ++$rowCount;
  13.     echo "\n";
  14. }

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

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

Объекты типа Zend_Db_Table_Rowset_Abstract доступны для сериализации. Сериализация производится так же, как и для отдельных объектов строк - вы можете сериализовать объект набора строк и восстановить его позднее.

Example #6 Сериализация набора строк

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

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

Example #7 Десериализация набора строк

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

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

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

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

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

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

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

Восстановление соединения для набора строк через метод setTable() делает то же самое для всех объектов строк, содержащихся в этом наборе строк.

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

Вы можете использовать альтернативный класс для наборов строк путем расширения класса Zend_Db_Table_Rowset_Abstract. Указывайте новый класс набора строк через имя в защищенном свойстве $_rowsetClass класса таблицы или в массиве, передаваемом в качестве аргумента конструктору объекта таблицы.

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

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

Стандартный класс Zend_Db_Rowset подходит для большинства случаев использования. Тем не менее, может потребоваться добавить свою логику в набор строк, специфический для данной таблицы. Например, новый метод может вычислять агрегированное значение для всех строк в наборе.

Example #10 Пример класса набора строк с новым методом

  1. class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
  2. {
  3.     /**
  4.      * Находит в текущем наборе строку с наибольшим
  5.      * значением в столбце 'updated_at'
  6.      */
  7.     public function getLatestUpdatedRow()
  8.     {
  9.         $max_updated_at = 0;
  10.         $latestRow = null;
  11.         foreach ($this as $row) {
  12.             if ($row->updated_at > $max_updated_at) {
  13.                 $latestRow = $row;
  14.             }
  15.         }
  16.         return $latestRow;
  17.     }
  18. }
  19.  
  20. class Bugs extends Zend_Db_Table_Abstract
  21. {
  22.     protected $_name = 'bugs';
  23.     protected $_rowsetClass = 'MyBugsRowset';
  24. }

Zend_Db_Table_Row