Tips & tricks CakePHP #2

В связи с выходом пре-беты 1.2 второй выпуск tips&tricks. Продолжаем знакомить Вас с идеями и проблемами версии 1.2, особенностями пре-беты, с которыми мы встретились в процессе разработки социальной сети.
Кроме того, мы завели себе блог на Хабре — присоединяйтесь, задавайте вопросы. Думаю, нам есть что обсудить.

Новый core.php!


Самое главное измение пре-беты – это новый формат файла core.php! Замените обязательно при обновлении этот файл и настройте его по усмотрению. В принципе, все описание параметров там уже есть.
Кстати, в database.php нормально заработало
'encoding' => 'utf8'

И никаких Вам изощрений с AppModel или mysql.php ;)

Sanitize->clean


Наконец-то привели в нормальный вид метод Sanitize – clean. Ранее он был ненастраиваемым и резал все, что можно в массивах. Теперь у метода появились параметры. Правда, в первой версии фильтр odd_spaces из-за недоработки не работал в первоначальной версии пре-беты, но благодаря автору статьи и системы тикетов проблема решена ;)
Итак, теперь легко настроить фильтры для очистки массивов от мусора.
Рассмотрим пример:
uses('sanitize');
$sanitize = new Sanitize();
$options = array(
'connection' => 'default',
'odd_spaces' => true,
'encode' => false,
'dollar' => true,
'carriage' => true,
'unicode' => true,
'escape' => false,
'backslash' => true
);
$array = $sanitize->clean($array, $options);


Вот так, все просто. Выставляете параметры, которые нужно задействовать, как true, а остальное как false.
Кстати, раз уж мы заговорили о Санитайзе, предложу вам довольно логичную конструкцию, которая быстро и просто защищает сайт.

Sanitize в Appcontroller


Поскольку все поступающие данные из форм поступают через $this->data, а над всеми контроллерами существует надстройка Appcontroller, то логично прокрутить следующий финт в beforeFilter:
class AppController extends Controller
{
var $components = array('RequestHandler');
var $helpers=array('javascript', 'ajax','navigation');

function beforeFilter() {
if(!empty($this->data)) {
uses('sanitize');
$sanitize = new Sanitize();
$options = array(
'connection' => 'default',
'odd_spaces' => true,
'encode' => false,
'dollar' => true,
'carriage' => true,
'unicode' => true,
'escape' => false,
'backslash' => true
);
$this->data = $sanitize->clean($this->data, $options);
}
}
}

Все, теперь все данные из форм режутся автоматически ;) Правда, тут на пути истинном встает новая фича версии 1.2 – named arguments.

Named arguments


Новая фича named args – это способ передачи информации через GET-запросы, т.е. через строку запроса, с помощью рутера. Некоторые простые переменные, которые Вам в каком-либо случае понадобились, можно теперь передавать так:
cakephp.org/posts/index/page:2/sort:title
Соответственно, у нас где-то должны быть созданы переменные page со значением 2 и sort со значением title.
Оказывается, из контроллера их очень легко получить:
$this->passedArgs[‘page’];.
$this->passedArgs[‘sort’];


Здесь, правда, возникает проблема, которая мной пока не исследована – что можно передавать таким образом? Не слабое ли это место в защите. Если да, то passedArgs имеет смысл также засунуть в sanitize, чтобы он эти аргументы хорошенько почистил :)

Класс Set


Эта удобная фича поможет в одну строчку разобрать целый массив, например, $this->data.
Предположим, Вы получили из БД таблицу users. Соответственно, массив данных выглядит так:
$users = array
(
0 => array
(
'User' => array
(
'id' => 1
, 'name' => 'Felix'
)
)
, 1 => array
(
'User' => array
(
'id' => 2
, 'name' => 'Bob'
)
)
, 2 => array
(
'User' => array
(
'id' => 3
, 'name' => 'Jim'
)
)
);


Хотите получить только имена пользователей? Да запросто:
$userNames = Set::extract($users, '{n}.User.name');


Как видите, {n} есть некий идентификатор скалярного массива. Соответственно, {n} можно помещать в различные места строки, меняя местонахождение этого скалярного массива в иерархии массива, содержащего скалярный.
Сам класс можно посмотреть отдельно, поскольку дело не ограничивается одним лишь extract. Есть merge, diff, contains, normalize. В общем, как всегда не хватает хелпа ;), а API здесь:
trac.cakephp.org/browser/branches/1.2.x.x/cake/libs/set.php

Мануал


Таки мануал для 1.2 был снова возвращен на место. Правда, еще есть много недопечатанного, но, видимо, его постоянно дополняют.
В открытом доступе в html-виде можно прочитать здесь:
tempdocs.cakephp.org/

Ждем Ваших замечаний и предложений. Также помните, что найденные проблемы можно оставить в виде тикета на сайте Кейка.
+6
1 декабря 2007, 12:26
15
avenu 46,1

комментарии (19)

–1
fxposter #
Спасибо, очень интересно!
0
avenu #
Не за что. Тоже кейк юзаете?
0
fxposter #
Скажем так - присматриваюсь к нормальному фреймворку на PHP. ZF понравился, но не в качестве фреймворка, скорее как библиотека. А вот по фреймворкам сейчас выбор - CodeIgniter или CakePHP.
0
avenu #
По поводу ZF абсолютно согласен. Он оченб гибкий, но когда дело доходит до моделей баз данных кейк однозначно начинает рулить, потому что создан для этого.
По поводу CodeIgniter ничего сказать не могу. :( Разве что у них там какая-то своя лицензия.
0
fxposter #
В ZF не хватает очень ActiveRecord :)
0
avenu #
Оно там сделано, но как-то совершенно по-левому. Т.е., в принципе, то, о чем я и говорил, для работы с моделями БД совершенно не предназначен.
Чего только стоит идея возвращения запроса к БД в виде ассоциативного массива, а результата поиска по модели в виде объекта. Спрашивается, если это все результаты запросов, почему бы их не сделать в виде одного способа вывода?
0
fxposter #
Не, ActiveRecord там нет. То, что там реализовано - это просто другая концепция работы с БД. Никакого отношения к ActiveRecord она не имеет. И, между прочим, тоже имеет право на жизнь. Но я хочу ActiveRecord. ;)
–2
huiTrix #
CakePHP для Ламеров. Используйте БИТРИКС ! Реальные пацаны только БУС'е лопатят :D

P.S. ШУЧУ )
0
avenu #
Ну Битрикс вообще другая тема. И денег стоит :)
–1
how #
Тупая шутка. CakePHP - это IMHO самый мощный фреймворк.
Кто хочет поспорить, пожалуйста, получите свои 10 баксов :)
php.southpark.com.ua/2007/holywar/
0
avenu #
Самый мощный в чем? Zend и Cake, например, вообще по-разному предлагают делать задачи. И Zend отвязан от моделей БД, что позволяет запросто строить сайты без БД.
Но вот возможность тащить из Zend их клевые библиотечки, типа Zend_Http и Zend_Lucene - это плюс =)))
0
how #
В том, чтобы делать приложения с нуля по хорошей методологии, которая позволяет не задумываться нам стандартными вещами (один ActiveRecord чего стоит).
А библиотеки можно и у Zend, и у PEAR одолжить - это не проблема.
0
avenu #
Это правда. Zend явно писали любители классов =)
0
hardtop #
Полезная информация. Спасибо! Сам выбираю фреймворк. Никак не могу остановиться на конкретном варианте. Symfony - очень тормозной, CodeIgniter - быстр, но прост. Cake в этом смысле некая золотая середина.

Меня волнуют 2 момента, подскажите, пожалуйста, кто знает:

1. Как делать для таблиц префиксы, например r4_news - чтобы можно было в одну базу поместить несколько проектов.

2. Как на фрейморке толково реализовать вложеную структуру сайта. Например,
domain.ru/about - текст
domain.ru/about/mission - текст
domain.ru/about/corpnews - новости компании
domain.ru/about/news - новости рынка

Спасибо.
0
avenu #
1. Можно подробнее?
2. Можно рутерами вручную поправить. Как конкретно нужно смотреть на практике.
0
hardtop #
1. Имя класса/модуля ведь совпадает с именем таблицы, так? А если база данных у меня одна (такой часто встречается у провайдеров), но есть 2 сайта. На них есть модуль news. Но у каждого сайта должно быть хранение своих данных. А таблица называется едино.

В своих наработках я указывал префик для таблицы. Например, r1_ для сайта №1 (r1_news), и r2_ для другого. Как это в фреймворке порешать изящно?
+1
how #
В CakePHP:
1. Указать префикс можно в config/database.php
2. Настроить можно как угодно в config/routes.php
Для статических или почти статических страниц там есть специальный контроллер pages.
0
hardtop #
Спасибо огромное! Пошел разбираться.

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