Главная   Новости   Поиск   
Азбука программиста




Яндекс.Метрика

Смотрим Yii PHP framework на примере запросов

Смотрим Yii PHP framework на примере запросов

Ближайшее время нередко приходится работать с фреймворком Yii. И время от времени появляются вопросы, ответы на которые довольно туманны. Сам фреймворк довольно удачный и документация подробная. Но классов много, и формат передачи данных их способам нередко является "подводным камнем" на пути к ироническому счастью. Посмотрим на данный фреймворк под призмой с помощью оператора IN.

Необходимо сформировать приблизительно таковой запрос:

SELECT * FROM tbl_users WHERE id IN (1, 2, 3)

В Полном руководстве на данную тему информации в явном виде Вы скорее всего не найдете, а копаться в способах CActiveRecord времени не всегда достаточно. С одной стороны, понятно как необходимо написать запрос, с другой – охото сделать это прекрасно, используя встроенную библиотеку. Копаться в документации желания особо нет, ведь на это уходит время, а запрос можно составить очень быстро. Но не все так просто.

Авторство принадлежит http://best-flash.com

Решение «в лоб»

$ids = array(1, 2, 3);
$dataProvider=new CActiveDataProvider('User',array( 'criteria'=>array( 'condition'=>'id IN ('.implode(',', $ids).')', ) ));
$this->render('admin',array( 'model'=>$dataProvider, ));

Здесь формируем массив со значениями, которые будут перечислены после IN. А потом, при помощи функции implode преобразуем его в строку и просто вставляем в запрос.

Недочеты такового подхода явны.

Во-1-х, код совершенно нечитаем.

Во-2-х, в реальном приложении значения для массива $ids будут откуда-то поступать, может быть, из характеристик запроса. И если массив $ids окажется пустым, то при выполнении запроса возникнет ошибка.

В-3-х, приобретенные значения необходимо проверить. А написать что-то вроде

'params'=>array(':id'=>implode(', ', $ids)),

не получится, т.к. итог работы функции implode будет взят в кавычки. Т.е. проверку нужно сделать за ранее.

Видите ли, появляются трудности фактически на пустом месте. Необходимо написать код проверок, решить, что делать с пустым массивом, потом протестировать этот код. И все ради решения классической задачи.

Решение при помощи библиотеки Yii.

Оно смотрится еще проще.

$model = User::model()->findAllByAttributes(array('id'=>array(1, 2, 3)));
$dataProvider=new CActiveDataProvider('User');
$dataProvider->setData($model);
$this->render('index',array( 'dataProvider'=>$dataProvider, ));

Способ findAllByAttributes класса CActiveRecord позволяет находить записи в БД по наименованию поля и значению. При всем этом если значение является массивом, то употребляется оператор IN.

Тот же самый код можно записать малость по другому.

$dataProvider=new CActiveDataProvider('User');
$dataProvider->criteria->addInCondition('id', array(1,2,3));
$this->render('index',array( 'dataProvider'=>$dataProvider, ));

Здесь уже употребляется способ addInCondition класса CDbCriteria. Если вы работаете с CActiveDataProvider, то получить доступ к объекту CDbCriteria можно при помощи характеристики criteria.

Несколько тестов

Попробуем в массиве передать строчку:

$dataProvider->criteria->addInCondition('id', array(1,2,'test'));

В итоге будет выполнен последующий запрос.

SELECT * FROM 'tbl_user' WHERE "id" IN (1, 2, 0)

Т.е. текстовое значение было заменено нулем, что полностью разумно, т.к. поле id имеет тип INT. Если запрос будет производиться к полю текстового типа, то текстовые и числовые значения будут вставлены в кавычках.

$dataProvider->criteria->addInCondition('id', array(1, 'admin','user'));

сформирует запрос

SELECT * FROM 'tbl_user' WHERE "id" IN ('1','admin', 'user')

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

$dataProvider->criteria->addInCondition('id', array());

SELECT * FROM 'tbl_user' WHERE 0=1

Видите ли, внедрение интегрированных библиотек всё-таки оправдывает время, потраченное на их исследование. Не брезгайте при работе с документацией Yii учесть один момент: Классы библиотеки плотно сплетены меж собой, потому находить необходимо не только лишь в методах класса, с которым вы конкретно работаете,  но и в глобальных методах родительских  объектов.

CActiveDataProvider употребляет CDbCriteria для формирования критерий, CPagination – для разбивки на странички, CSort – для сортировки и т.д. Чем больше работаешь с фреймворком, тем логичнее кажутся решения разработчиков и тем проще ориентироваться в документации



Безопасность

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

Читать далее