Как мы знаем, фреймворк Kohana предлагает возможность доступа к БД различными способами (например, прямой запрос через $this->db->query() или Query Builder). Так или иначе, мы получаем на выходе некий объект класса Database_Result. Обычно мы просто используем его в циклах типа foreach, не задумываясь о его возможностях. Давайте рассмотрим внимательнее этот интересный объект.
Сам класс описан в файле /system/libraries/drivers/Database.php. Обратите внимание, что он абстрактный! Его назначение — описать интерфейсы, которые должны будут реализовать его потомки (т.е. драйверы для конкретных СУБД, например класс Mysql_Result в /system/libraries/drivers/Database/mysql.php). Сначала отметим, что он создан на основе трех SPL-интерфейсов:
abstract class Database_Result implements ArrayAccess, Iterator, Countable { ... } |
Эти интерфейсы описывают методы доступа к элементам класса как к массиву.
- ArrayAccess — с его помощью организовывается доступ к свойствам класса как к элементам массива. В общем-то, необходимо реализовать методы для работы со смещениями (offset) — получение/изменение/удаление/проверка на существование. В реализации Kohana разрешен доступ только на чтение, т.е. мы можем получить $result['name'], но не можем его удалить или переопределить.
- Countable — интерфейс для подсчета количества элементов. Единственный метод count() в реализации Kohana возвращает количество записей в БД для запросов выборки (SELECT, SHOW и т.д.) или количество затронутых записей для изменяющих запросов (DELETE, INSERT, UPDATE и т.д.).
- Iterator — по названию понятно, что интерфейс описывает способы перебора элементов объекта. Просто перечислю методы: current() (текущий элемент), key() (ключ текущего элемента, т.е. порядковый номер), next() (переход к следующей записи), prev()(возврат к предыдущей записи), rewind() (переход к началу массива), valid() (проверка, существует ли элемент при текущем смещении, вызывается после next() и rewind()).
Итак, данные методы позволяют нам использовать итерацию (for/foreach и т.д.) при работе с объектом Database_Result. Что мы еще имеем?
- insert_id() — возвращает последний сгенерированный СУБД auto_increment‘ный ключ. Имеет смысл только для изменяющих запросов.
- list_fields() — возвращает список полей в полученном ответе.
- result($object = TRUE, $type = FALSE) — позволяет получить результат работы запроса (собственно сами записи выборки) в удобной для нас форме. На входе два параметра:
- $object — определяет, отдавать результат в виде объекта ($object==TRUE) или как массив (FALSE)
- $type — уточняем, что именно ожидаем. Если первый параметр был TRUE (т.е. возвращается объект, а не массив), то мы можем указать имя класса, объектом которого будет возвращаемый результат. В случае массива, можно выбрать тип массива (MYSQL_ASSOC, MYSQL_NUM или MYSQL_BOTH для MySQL-драйвера).
В офф. документации приводится хороший пример:
class CircleObject { function area() { return $this->radius * $this->radius * 3.14; } } $query = $this->db->query("SELECT `radius` FROM `circles`"); $query->result(TRUE, 'CircleObject'); foreach ($query as $row) { echo '<p>'.$row->area().'</p>'; }
Т.е. в качестве результата возвращен массив объектов класса CircleObject, в каждом из которых вызов метода area() будет использовать как раз данные из выполненного запроса, а конкретно — поле `radius`.
- result_array($object = NULL, $type = FALSE) — аналогичен методу result, только ответ приходит в виде массива, а не экземпляра класса Database_Result. По умолчанию будут взяты параметры из конфигурации проекта (/application/config/database.php).
- seek($offset) — переход к записи под номером $offset. Возвращает TRUE, если переход успешен, иначе FALSE.
- sql() — возвращает примененный при формирования результата текст SQL-запроса.
Итак, чем могут быть полезны эти методы?
1. Получение количества записей вызовом одного метода count() вместо подсчета размера итогового массива
2. В случае запроса одной записи можно из модели возвращать только ее — через метод current()
3. «Хитрые» преобразования данных с помощью result() и result_array() в собственные классы.
и т.д.
Комментарии (0)
Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.