Объекты доступа к данным (DAO)

Объекты доступа к данным (DAO) предоставляют общий API для доступа к данным, хранящимся в различных СУБД. Это позволяет без проблем поменять используемую СУБД на любую другую без необходимости изменения кода, использующего DAO для доступа к данным.

Yii DAO является надстройкой над PHP Data Objects (PDO) - расширением, которое предоставляет унифицированный доступ к данным многих популярных СУБД, таких как MySQL, PostgreSQL. Поэтому для использования Yii DAO необходимо, чтобы были установлены расширение PDO и соответствующий используемой базе данных драйвер PDO (например, PDO_MYSQL).

Yii DAO состоит из четырёх основных классов:

Далее мы проиллюстрируем использование Yii DAO на различных примерах.

Соединение с базой данных

Для установления соединения с базой необходимо создать экземпляр класса CDbConnection и активировать его. Дополнительная информация, необходимая для подключения к БД (хост, порт, имя пользователя, пароль и т.д.), указывается в DSN (Data Source Name). В случае возникновения ошибки в процессе соединения с БД будет выброшено исключение (например, неверный DSN или неправильные имя пользователя/пароль).



Формат DSN зависит от используемого драйвера PDO. Как правило, DSN состоит из имени драйвера PDO, за которым следует двоеточие, далее указываются параметры подключения, соответствующие синтаксису подключения используемого драйвера. Подробнее с этим можно ознакомиться в документации PDO. Ниже представлены несколько основных форматов DSN:

Поскольку CDbConnection наследует класс CApplicationComponent, мы можем использовать его в качестве компонента приложения. Для этого нужно настроить компонент db в конфигурации приложения следующим образом:



Теперь мы можем получить доступ к соединению с БД через Yii::app()->db. Чтобы соединение не активировалось автоматически, необходимо установить значение CDbConnection::autoConnect в false. Этот способ даёт нам возможность использовать одно и то же подключение к БД в любом месте кода.

Выполнение SQL-запросов

Когда соединение с БД установлено, мы можем выполнять SQL-запросы, используя CDbCommand. Для этого необходимо создать экземпляр класса CDbCommand путём вызова CDbConnection::createCommand(), указав SQL-выражение:



Существуют два способа выполнения SQL-запросов с использованием CDbCommand:

Если в процессе выполнения SQL-запроса возникнет ошибка, то будет выброшено исключение.



Обработка результатов запроса

После того как CDbCommand::query() создаст экземпляр класса CDbDataReader, мы можем получить результат запроса построчно путём повторения вызовов метода CDbDataReader::read(). Для получения данных строка за строкой можно также использовать CDbDataReader в конструкциях foreach.



Примечание: Все методы queryXXX(), в отличие от query(), возвращают данные напрямую. Например, метод queryRow() возвращает массив, соответствующий первой строке результата запроса.

Использование транзакций

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

Эту последовательность действий можно реализовать следующим образом:



Привязка параметров

Для предотвращения SQL-инъекций и повышения производительности при выполнении однотипных SQL-запросов мы можем «подготавливать» SQL-выражения, используя маркеры параметров (placeholders), которые в процессе привязки будут заменяться на реальные значения.

Маркеры параметров могут быть именованными (уникальные маркеры) или неименованными (вопросительные знаки). Для замены маркеров на реальные значения нужно вызвать методы CDbCommand::bindParam() или CDbCommand::bindValue(). Экранировать или заключать в кавычки значения параметров не нужно, используемый драйвер базы данных всё сделает сам. Привязку параметров необходимо осуществить до выполнения SQL-запроса.



Методы bindParam() и bindValue() очень похожи. Единственное различие состоит в том, что первый привязывает параметр к ссылке на переменную PHP, а второй — к значению. Для параметров, представляющих большой объем данных, с точки зрения производительности предпочтительнее использовать метод bindParam().

Подробнее о привязке параметров можно узнать в соответствующей документации PHP.

Привязка полей

При получении результатов запроса мы также можем привязать поля таблицы к переменным PHP. Это позволяет автоматически присваивать значения переменным при чтении очередной строки:



Использование префиксов таблиц

Yii предоставляет встроенную поддержку префиксов таблиц. Префикс таблиц — это строка, предваряющая имена таблиц в текущей подключённой БД. В основном, префиксы используются на виртуальном (shared) хостинге, где к одной БД подключаются несколько приложений, использующих различные префиксы таблиц в целях избежания конфликтов имён. Например, одно приложение использует префикс tbl_, а другое — yii_.

Для использования префикса таблиц установите свойство CDbConnection::tablePrefix. Затем в SQL-выражениях используйте {{TableName}} для указания имён таблиц, где TableName — имя таблицы без префикса. Например, если БД содержит таблицу tbl_user, где tbl_ — это префикс таблиц, то мы можем использовать следующий код для получения списка пользователей: