К основному контенту

Сообщения

Показаны сообщения с ярлыком "cakephp"

Частичный переезд

Я решил оживить домен handmadesite.net и переношу все посты про Shop-Script, Cake, ZendFramework, PHP и т.п. туда. А то мой “уютный дневничок” стал похож непойми на что. :-) Ну и еще там можно подписываться на каменты, да и вообще… Счас потихоньку все более менее свежие тематические посты дублирую туда, а здесь запрещаю их комментарии. Вот. Велкам всем, кому интересна эта тематика. :-)

Почитать о CakePHP

Некоторое время назад наткнулся на хороший и полезный русскоязычный блог посвященный CakеPHP. Можете добавить к себе в закладки и/или RSS-ридер: Программируем на CakePHP . Мне понравилось. Посты достаточно разноплановые, но все в той или иной степени полезные. Самое важное – автор не забросил свое начинание после 2-3 постов, так что есть надежда, что проект будет жить и дальше. Еще интересный проект, правда неоконченный. Марафон MVC фреймворков . Автор пытается создать проект на разных фреймворках и оценивает различные особенности каждого. Участвуют ASP.NET MVC, CakePHP 1.2RC2, Catalyst 5.7, Django 0.96 и RoR 2.1. Мысль давно сидящая в голове : а не пора-ли мне с Blogger’а съехать на standalone? :-)

Киянкой по голове – лекарство от болезни роста

Окончание о болезнях роста баз данных . Как и предсказывали друзья , переход на InnoDB и шаманство с типами связующих полей двух больших таблиц в MySQL не дали сколько-нибудь приемлемого результата. После размышлений о непредсказуемом результате, смысле жизни, затратах на смену СУБД, от перевода всего на PostgreSQL решил отказаться. Против лома нет приема и построчный перебор результатов запроса решил сделать обычными методами PHP, в обход Cake. Тоже, скажем прямо, не Cake way :-) Первым делом поискал гугловской группе сообщения на аналогичную тему. Таки да, есть люди со схожими запросами . Более того, во глубине сибирских руд классов CakePHP есть метод fetchRow, но он неинтересен совершенно. При выполнении запроса Cake хранит ссылку на результат последнего запроса у себя в свойстве и перебирать построчно результаты можно, только если при этом не выполнять никаких других запросов. В противном случае результат запроса, естественно, будет перезаписан. Поэтому задача перебора строк...

Неочевидное поведение метода updateAll

Как неожиданно выяснилось, методу Model::updateAll совершенно наплевать на указания contain, усли подключен ContainableBahavior , а также на значение свойства Model::recursive. Несмотря ни на что, при вызове Model::updateAll все равно подключались все зависимые модели. Вылечилось жесткой командой (дело было в методе модели): $this->unbindModel(array( 'belongsTo'=>array_keys($this->belongsTo), 'hasOne'=>array_keys($this->hasOne), 'hasMany'=>array_keys($this->hasMany) )); Но осадочек в душе остался. :-)

Значение именованного параметра

Совсем крошечный метод, который можно поместить в AppController. Возвращает значение именованного параметра, или null , если такого параметра нет. Просто чтоб не повторять одинаковый код в разных методах. /************************************ * Returns a value of named parameter * or null if it isn't exists ************************************/ protected function named($paramName) { if (!array_key_exists($paramName, $this->params['named'])) { return null; } return $this->params['named'][$paramName]; }

Составные первичные индексы и CakePHP

Общеизвестный факт: CakePHP не поддерживает составные первичные индексы. Разработчики предлагают добавить в качестве первичного индекса поле id, а составной индекс из нескольких полей просто сделать уникальным. Это, в общем-то, разумно — первичный индекс используется в моделях для установления и проверки связей, поэтому добавление процедур для работы с составными индексами неплохо увеличит объем кода, что, в свою очередь, скажется на производительности. Более того, использование составных индексов в качестве первичных — редкое явление, хотя я сходу придумал пару ситуаций когда это оправданно. Схема с добавлением еще одного поля, предлагаемая разработчиками Cake неплохо функционирует, однако контроль за уникальностью составного индекса перекладывается на веб-разработчика. Для определения, вставляется-ли новая запись (INSERT…) или обновляется старая (UPDATE…) при вызове из метода save(), Cake поступает очень просто: продеряет наличие в элемента массива $this->data[‘Model’][‘id’]...

Используем TreeBehavior в CakePHP 1.2

Это вовсе не полное руководство, а пара замечаний к практическому использованию. TreeBehavior – весьма полезный компонент CakePHP, реализующий паттерн Nested Sets для указанной модели. Если что-то непонятно, то вот ссылки: Про паттерны древовидных структур Что такое Behavior в CakePHP 1.2 TreeBehavior TreeBehavior позволяет хранить несколько корневых элементов, у которых родительский id равен NULL. Не поддавайтесь искушению – для себя сделайте отдельный корневой элемент. Большинство функций, например Model::children не работают с идентификатором записи равной NULL. Поэтому, если возникнет необходимость получить всех потомков корня, придется сначала выбрать самостоятельно все элементы с parent_id=NULL, а потом для каждого из них вызвать Model::children(). То есть, если создается, скажем, структурированный каталог сайтов, не надо поддаваться искушению добавить основные разделы, как корневые – создайте сначала “совсем-совсем” корневой элемент с именем, скажем, ROOT,...

Значения полей created/updated по-умолчанию в CakePHP

Не секрет, что некоторые поля в моделях Cake умеет заполнять самостоятельно, основываясь на названии поля. Например в поля created и updated (или modified ), если у них тип DATETIME, будут подставляться даты создания и изменения. При создании таблицы надо выбрать значение по умолчанию для этих полей. В документации на Cake 1.2 недавно появилось предупреждение на эту тему, но ктож все время будет документацию перечитывать? :-) У created и updated значение по-умолчанию должно быть NULL . В общем-то все будет прекрасно работать и со значением “0000-00-00 00:00:00”, которое phpMyAdmin пытается установить самостоятельно, но ровно до того момента, когда появится необходимость добавить несколько записей и, в соответствии с рекомендациями ВЦСПС разработчиков, перед каждым вызовом $Model::save(…) вызывать $Model::create(…). $Model->create() заполняет $Model::data значениями по-умолчанию для всех полей, а $Model::save() изменяет значения created / updated только если они не опреде...

CakePHP l10n

Собственно этот пост скорее всего лучше было бы не писать, а просто положить ссылку в del.icio.us. А вдруг еще кому-нибудь пригодится? :-) На данный момент это, пожалуй, самое подробное описание локализации CakePHP 1.2 . Добавить совершенно нечего. :-)

Pagination в CakePHP 1.2. Небольшая хитрость

Этот пост устарел! Читайте по ссылке исправленную и сильно переработанную версию ! This is totally outdated article! Follow the link to see a more complete version! Sorry. The newwer post in russian too. Как уже писал , Containable behaivior , который отлично справляется с задачей выборки только нужных для данного действия (action). И при небольшой модификации отлично работает с методом pagination . Однако есть одна неприятная вещь, опять же связанная с тем, что pagination вызывает последовательно 2 метода модели — сначала для подсчета количества записей, а потом для выборки. При попытке подсчитать количество записей у модели с большим количеством связей, paginator делает SQL запрос SELECT COUNT(*) со всеми положенными JOIN'ами, что при больших объемах данных существенно увеличивает время выполнения запроса. Особенно, если при этом еще и сортировку делать надо. Этот факт сильно раздражает, если в итоге нужно всего-лишь количество записей в основной модели. Выход есть. ...

Модели в CakePHP

Беда какая-то с реализацией моделей в Cake. Не то, чтобы совсем уж плохо, или не то, чтобы их совсем нет, как в Zend Framework , но реализация пока хромает. Особенно с рекурсией туго. Т.е. если 1 уровень рекурсии, то все хорошо, но если нужно 2 уровня, то уже плохо. Например, есть у нас модель "Лекарство", связанная с моделями "Производитель" и "Цена", а "Цена" связана с моделью "Валюта". Связи примерно такие: Лекарство belongsTo Производитель Производитель hasMany Лекарство Лекарство hasOne Цена Цена belongsTo Валюта Обратная связь от Производителя — чтоб можно было получить все продукты, ему принадлежащие. Однако при попытке получить данные о лекарстве получается полная фигня — либо, при recursive=1 не получаем Валюту, либо при recursive=2 получаем на втором уровне все продукты от Производитель. Для этого есть несколько решений. как для версии 1.1, так и 1.2. Чаще всего предлагается сде...

Разные шаблоны для сайта и админской части

Наиболее изящное решение для подключения отдельного шаблона админской части. Для Cake 1.1: В каталоге app создаем (если его там нет) файл app_controller.php и добавляем туда такие строчки: class AppController extends Controller { function beforeRender() { if(isset($this->params[CAKE_ADMIN])) { $this->layout = 'admin'; } } Теперь для админской части будет загружаться шаблон admin.thtml Респект gwoo :) Upd: 18 декабря 2007 Для Cake 1.2 В версии 1.2 указанное решение работать не будет. Хотя бы потому, что нет константы CAKE_ADMIN. Но решение похожее. Во-первых app_controller.php, от которого наследуются все контроллеры, переехал из корня в папку с контроллерами :-), теперь его надо создавать в /app/controllers. А метод beforeRender должен выглядеть так: function beforeRender() { if(isset($this->params['admin'])) { $this->layout = 'admin'; } } Надо обратить внимание, что шаблоны в версии 1.2 п...