Как стать автором
Обновить

Комментарии 82

НЛО прилетело и опубликовало эту надпись здесь
так в блог Кохана переноси быстро!))
Нужно продвигать сей чудесный фреймфорк. ато у нас он почему-то еще относительно не популярен.
А и спасибо за статью. Я бы сам тоже написал что-нить. Но все времени и сил не хватает.
Перенес =)
Мое первое знакомство прошло на ура, только после того как они обновили фреймворк до новой версии модуль генерации форм убрали из пакета. На етом мой интерес и закончился )
Забавное название у CMS. Можно еще одну систему управления создать, которой пользоваться иногда для проектов на стороне и назвать ее «Kohanka» ;)
:) Дело в том, что не все знают украинский язык ;)
Для справки: «Кохана» на украинском означает «Любимая», а вот «Коханка» — «Любовница»

Так, на всякий случай ;)
Главное — чтобы с Kohank'ой не пришлось заниматься тем, для чего обычно держат любовниц ^_^
НЛО прилетело и опубликовало эту надпись здесь
Только не в моск… (с)
Поясни пожалуйста
$categories = ORM::factory('category')->where('parent_id', 0)->find_all();
foreach($categories as $l) {
...
foreach($l->children as $n) {
$_tmp->count+= ORM::factory('item')->where('category_id', $n->id)->count_all();
}
...
}

Каждое обращение к ORM это один запрос к базе?
Если да, то наверное было бы логичным сделать это всё одним запросом чем многими в цикле.
Дело в том, что для подсчета кол-ва всех записей в подкатегория, в любом случае необходим их перебор, так, что кол-во запросов не измениться. Тем более, в первом вызове ORM мы получаем список главных категорий, то мы никак не сможем его перебрать из этой же инстанции.

Хотя, при действительно большем кол-ве подкатегорий (у меня в исходном проекте их 105) запросов к базе будет не меньше, так-что думаю вставить в items колонку с главной категорией, которой принадлежит подкатегория. Если у кого-то есть лучшие решения — с удовольствием выслушаю =)
*и мы никак не сможем перебрать из этой же инстанции все объявления, только подкатегории.
НЛО прилетело и опубликовало эту надпись здесь
Если просто на sql, то в принципе посчитать можно таким запросом.
SELECT count(*) as count, category_id from items group by category_id
Дело в том, что если дать такой запрос базе через ORM, то в итоге мы получаем не массив, как должно было бы быть, а целое число, кол-во объявлений в подкатегории самого первого объявления. Вариант ниже, с IN, к сожалению, тоже не подходит.

Происдел всю ночь, так и не придя к какому-либо выводу, видимо придется всё-таки добавить поле в исходный проект, если «с утра» ничего в голову не придет, а с примером — буду думать…
НЛО прилетело и опубликовало эту надпись здесь
Согласен, из примера пока этот кусок уберу вообще.

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

Темболее есть все причины думать, что можно ограничится 12 запросами, при довольно изящной реализации, но пока не знаю точно как, будем работать =)
А почему бы вам не сделать запрос в методе orm модели, через $this->db->query()?
В том то и дело, что хотелось бы, для наглядности, реализовать это всё, не обращаясь на прямую к базе. Всё только через ORM.

Тут ведь не в функционале суть, а в его реализации.
А если вам не подходит GROUP, а нужно из определенных категорий, то используйте
SELETC BLA...BLA FROM BLA WHERE CategoryId IN ('1','2','3')
Да, я это и имел ввиду.
С каждым днем всё больше убеждаюсь в неоправданности ORM и ActiveRecords.
Вау, хорошее вступление, в фреймворк но ещё для самых торопливых, пожалуйста, добавьте к статье архив с вашей субдирректорией application.

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

По поводу сложности — к сожалению я с другими фреймворкими не сталкивался, а Kohana выбрал поддавшись лишь минутной слабости и, хочу заметить, ниразу не пожалел. А статьей как-раз и хочу помочь, как Вы сказали, не таким, как я =)
Я не вникал особо в код, но сразу в глаза бросились 3 момента:

1. Названия таблиц без префиксов. Из в принципе нельзя использовать или тут только для примера?
2. А чего при создании таблиц где-то указано DEFAULT CHARSET=utf8; а где-то нет? Ну понятно, для примера, но всеже если этот пример выполнить в баде где по дефолту Win-1251 установлено, что тогда будет? Не съедут ли данные?
3. ORM_Tree работает с деревьями на основе parent_id? Только с ними? Просто не самый лучший способ хранить деревья.

Да, и во вьювах на мой взгляд конструкции
<?php if(Auth::instance()->logged_in()): ?>

<?php else: ?>

<?php endif;>

более понятны, нежели

<?php if(Auth::instance()->logged_in()) { ?>

<?php } else { ?>

<?php } ?>


но это мое личное мнение.
Префиксы, конечно же, можно использовать, задаются они в config/database.php значением $config['default']['table_prefix'] и доставляются, естественно, автоматом. А в коде — просто для примера, чтобы не усложнять.

С DEFAULT CHARSET — виноват, сейчас исправлюсь.

По поводу ORM_Tree — нет, в описании модели класса можно объявить свойство protected $parent_key, которое будет содержать имя колонки с id родителя.

А шаблоны — не раз уже затрагивалась эта тема, но мне так удобнее, это просто пример =)
По поводу ORM_Tree — нет, в описании модели класса можно объявить свойство protected $parent_key, которое будет содержать имя колонки с id родителя.


Вы, кажется, не поняли вопроса. Я спрашивал не про имя колонки, а про алгоритм хранения дерева. Тут используется алгоритм на основе хранения id родителя (parent_id), что вообще-то часто достаточно ресурсоемко. Кроме этого существуют другие, менее ресурсоемкие алгоритмы (Depth-Level, Nested Set). Вопрос — поддерживае ли их ORM_Tree?
Прошу прощения. Насколько я понял из кода, ORM_Tree — это расширенный класс ORM, а ORM_Tree::parent просто возвращает запись, в которой id равен значению $parent_key текущего объекта. Сообветственно, ORM_Tree::children вернет объект с записями, у который id текщего объекта заявлен как $parent_key.

Хотя, существует переписаный вариант библиотеки от CI MPTT для Kohana, но я с ним дела, к сожалению, не имел.
А почему везде советуют использовать префиксы?
Единственный плюс вижу в том, что бы в одной базе хранить данные нескольких проектов, но по моему уже 90% хостеров даже по самым дешевым тарифам дают 3-5 бд.
А минусом является то, что надо не забыть его подставлять в запросы.
У 90% из этих 90% :) количество БД соответствует (а то и меньше) количеству сайтов на аккаунте, а значит без префиксов (точнее без любого механизма избежания коллизий в именовании таблиц) нельзя (вернее могут быть проблемы, скажем таблица users очень популярна) запустить два движка на одном сайте, например, собственно CMS и популярный форумный двиг
просто иногда дампить удобно. Часть таблиц (ядро) идет с префиксом SYS_, их не трогаю при дампе контента. Или например, если логирование идет в базу, то зачастую нет смысла переносить таблицы с префиксом LOG_
Есть Kohana-mptt для дерева.
По моему опыту скажу, что в условии большого количества кода, вариант с фигурными скобками гораздо легче выявить в тексте, в отличие от варианта предложенного вами, так как в большенстве ide имеется подсветка начала и конца скобок.
Эм… Вы уж простите за оффтопик, но первое, что бросилось в глаза — это отсутствие FOREIGN KEY's во всех таблицах БД и, соответственно, использование MyISAM.
Вы действительно настолько уверенны в PHP и konaha, что готовы переложить на него полностью всю заботу о синхронизации данных в БД? Не страшно?
Ну, не думаю, что в контексте примера это так критично.
В контексте примера — я бы добавил для общего понимания. И обоснование выбора — так же. В качестве best practice.
«Кохана» — в переводе с украинского на русский — означает «любимая», занятно )

Старый друг — лучше новых двух… Меня, как программиста в универе учили лени, т.е. изначально изучать старое, и годами проверенное, чем искать (и не дай Бог) изобретать что-либо новое…
НЛО прилетело и опубликовало эту надпись здесь
Ребят, я не понимаю, как в современном фреймворке допустимо такое
 $_tmp->id = $l->id;
 $_tmp->name = $l->name;
 $_tmp->children = $l->children;
Я несколько старомоден =D

А если серьезно, то я не знаю, как ещё передать всего три свойства одного класса другому. Если подскажете, буду весьма признателен.
А через list() нельзя?
Можно, получится одна длинная стока (длинее, чем эти 3), которая еще и схватит немного лишних ресурсов. Проще просто исходные 3 строки в одну записать.
Не впечатлило.
Как-то, что-ли не изящно? Во всяком случае не увидел ничего, что не было бы в symfony или zend'e… Хотя конечно это и не все возможности этого фреймворка, я уверен.
Вы правы, изящности не хватает, но всё-же не следует забывать, что это не обзорная статья, а такой-себе user-guide, для начинающих, с небольшим кол-вом опыта, для которых приимущество есть не изящность, а порстота.
выглядит очень неряшливо, уж не знаю чья это заслуга, ваша или коханы. но что очевидно, используются т.н. fat controllers, то есть в контроллерах помимо логики управления находятся еще логика отображения и обработки данных. по уму должен нужно стараться этого избегать и писать в соответствующих местах — view и model.
Не сомневайтесь, моя.

Дело в том, что я ещё не шибко хорошо пишу, а т.к. про этот фреймворк мало кто знает, и ещё меньше про него пишут, пришлось руководствоваться принципом «кто, если не я», Вы уж простите.

Надеюсь в далнейшем инициативу перехавтят авторы с гораздо большим опытом и способностями к его изложению.
а не подскажете, где можно посмотреть на код на Kohana или CI который можно было бы считать образцом для подражания? только не простенькие примеры из туториалов.
дело в том что сейчас я пишу первый, но относительно сложный проект на CI и возникают всякие вопросы, например — где проводить валидацию данных, в модели или контроллере, как можно бы сделать view-обертку для других view и т.п. хотелось бы глянуть как это все принято правильно делать.
Валидацию лучше проводить на уровне контроллеров, имхо.

Насчет view-обертки — в CI нет встроенных средств а-ля Layout в Zend Framework. Лично я использую библиотеку «Template»: официальная страничка и ветка на форуме CI.
я не считаю игнитер образцом для подражания вообще. советовать другие фреймворки в тематическом блоге считается моветоном, поэтому загляните в мой профиль, чтобы узнать на что смотреть.
валидация данных должна проводится в модели тчк
Если отдавать валидацию модели, что чисто теоретически выглядит более правильным, однажды можно уткнуться в то, что набор правил должен меняться в зависимости от тех или иных условий и вот тогда вся красота рушится…
Это именно то, что нужно для старта — реальный пример разработки приложения с помощью Kohana. Спасибо!
Чтото многовато кода для доски объявлений.
Это ведь пример, а не готовое решение, о чем я уже писал ваше. Если у вас есть предложения по оптимизации, с радостью их рассмотрю.
Дело в том, что для меня этот пост – первое впечатление в Kohana вообще.
И первое впечатление такое – для доски объявлений слишком много кода. Имхо надо больше гибкости. И меньше кода. Но если большая часть этого кода будет реиспользоваться в других частях приложения (не копипаст а именно использоваться), тогда я возьму слово назад =).
Тут примерно половина — авторизация пользователей на сате.
Вижу =). Беру слово назад.
И ещё, у Вас ссылка на ORM ведёт на wikipedia.ru. Надо на wikipedia.org (http://ru.wikipedia.org/wiki/ORM)
Прошу прощения… Уже исправл.
Спасибо, отличная статья!
Статья хороша, но у меня вопрос — сколько запросов к базе идет при отображении того или иного view?
Много. Для 8 объвлений — 17 запросов (в том числе и запросы к таблице ползователей и их прав).
А для 16, 32?
Я хочу понять зависимость кол-ва запросов от объема данных…
> Для работы с пользователями у нас есть стандартные модели модуля Auth, для обращения к статьям и категориям, создадим свои — создайте файл /application/models/category.php и пропишите в нем следующий класс:

Сие предложение ввело меня в ступор, дальнейшие объяснения понять не смог.
Извините, но что именно не понятно?

Модуль Auth уже имеет в своем арсенале необхдимые для него модели и требует несколько таблиц от базы для хранения своих данных. Далее я предлагаю создать модели, необходимые для хранения структуры категорий и объявлений.
> Извините, но что именно не понятно?

Русская языка… Может так будет понятнее:

«У Маши в корзине лежит пять яблок, для того чтобы кушать, купила еще — зашла в магазин и заплатила.»

Вопросы:

Пять яблок для того чтобы кушать?

или

Для того чтобы кушать, купила еще?

Ы?
Лично я считаю, что цитируемая Вами фраза вполне понятна, и если у Вас возникли трудности с её пониманием, то мне жаль.

В случае наличия у Вас более подходящих вариантов для её изложения, я с радостью заменю исходный на Ваш, при целесообразности сиих манипуляций.
Я с радостью подсказал бы вам. Но мне непонятно что вы имеете в виду.
Пытаюсь разобраться и не пойму где происходит проверка на то является ли категория главной или нет? Или вся надежда на то, что список в форме заполнен так, что id может быть только у подкатегорий?
У главных категорий id = 0, по этому признаку и отбераем главные.
Видимо непонятно выразился, попробую еще раз.
Не могу найти место в коде, где отсекаются запросы на добавление объявления с указанием category_id скажем 1.
ORM удобная весч. Но я бы вам не советовал привыкать его использовать в контроллерах или моделях Публичной части сайта.
Может быть только в реализации Админки сайта.

ORM в своей работе, обычно, ОЧЕНЬ активно посылает SQL-запросы, и даже для простых задач число запросов может исчисляться десятками… Для меня это много…
Может я старомоден ) но если при генерации страницы мой Движек делает более 7-10 запросов, то я начинаю нервничать и искать где что можно оптимизировать или закешировать…
в случае использования ORM такая гибкость исчезает, к сожалению…
Согласен со всем, что Вы сказали.

Я ещё не сильно разобрался, где и что лучше вызывать, но на основе комментариев для себя уже выделил несколько важных моментов, которые в дальнейшем планирую использовать и учитывать.
Могу конечно ошибаться, но надо ли выделять отдельно работу с категориями и подкатегориями? Нельзя использовать один и тот же метод?
Можно, если немного поменять модель роутинга и проверять, является ли категория главной, и вызывать ORM::factory('category', $params), либо же ORM::factory('category', $params)->children в ином случае. Но, по-моему, такой подход не сильно подходит для примера, где важнее наглядность.
Только начал разбираться — вообще интересный фреймворк конечно. Но только есть один момент из примера спорный. По крайней мере как для программиста с++.
Зачем в каждом классе-наследнике Template_Controller переопределяется поле template? Если это делается для определение дефолтового значения переменной в классе-наследнике — то по канонам ооп это должно делаться в конструкторе класса. Собственно, я поэтому вместо Template_Controller написал свой базовый абстрактный класс, который при рендеринге переменной проверяет инициализацию этой по сути абстрактной переменной.
Для знакомства с Kohana решил выполнить пример. Все отлично. Все получилось. Все работает с одним «но». Медленно. Страничка формируется около 3-х секунд. Возможно, проблема в площадке (FirstVDS, Тариф «Старт»)?
Да, скорее всего дело в площадке. Для сравнения, у меня на домашней машине (384Mb, 1.5GHz) полное формирование страницы занимает порядка 0.3 секунды.
очень напрягает метод создания форм. работаю с фреймворком symfony — там это делается намного удобнее
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.