>У Вас используется некая структура сбоку, вместо модели документа, чтобы получить схожий результат.
Да, у меня используется лишнее действие. Перед отдачей данных шаблону, происходит ручная предвыборка вторичных объектов.
Кстати, эта задача легко автоматизируется. Загрузчику массива объектов можно передать параметр загрузки вторичных объектов, зависимых от загружаемых.
Мысль интересная, хотя кеширующая предвыборка у меня и занимает обычно только три коротких строки, но используется это решение часто. Можно автоматизировать.
Один — генерация объектов комментариев по тому или иному критерию.
Потом сбор ID пользователей, обычно — PHP-циклом.
Потом второй запрос — загрузка объектов пользователей. Хотя напрямую я эти объекты использовать не буду, но они закешируются. И потом, при 50 загрузках объектов этих пользователей, они будут браться не из БД, а из кеша.
Я выше этот момент описал :)
…
Можно извратиться и сделать вообще один запрос, прописав все нужные параметры пользователя прямо в объекте комментария, но это сложно, некрасиво и может привести прямо к потере производительности, т.к. на сложных БД JOIN может быть много тяжелее двух простых вызовов.
Это когда есть возможность править отданные базой заказчика данные :) В этом случае можно заставить его и просто слеши поменять, скажем, на скобки, как это я сделал.
Но до того, пока понял такое поведение IE, пришлось потратить уйму времени на эксперименты. Плюс объяснение таких особенностей заказчику задним числом тоже не очень хорошо :)
— Ядро передаёт ссылку загрузчику объектов, тот грузит объект.
— Ядро вызывает метод content() и выводит результат
Загрузчик объектов:
— Находит нужный класс по его имени или по привязке форматов URL к классам.
— Создаёт объект класса.
— Инициализирует класс.
Инициализаторы классов могут быть разные. Самый популярный — это, конечно, использующий mysql-бэкенд, выполняющий ORM-маппинг. Хотя может быть и иным (часто практикую загрузку их статических *.txt, реже — XML или Oracle) или вообще отсутствовать (тоже весьма распространено).
В принципе, тут никакой отложенной загрузки нет, но я с задачей множественных обращений к БД справляюсь, используя мультизагрузку объектов и кеши.
Скажем, нужно вывести список товаров на страницу.
Объект этой страницы автоматически, при создании, ничего из БД не грузит.
Но метод content() вызовет метод local_template_data_set(), возвращающий хеш переменных для насыщения шаблона.
Вот этот метод, как раз, и может описать загрузку объектов. Например, так:
В итоге если выводимые объекты будут автономны и не потребуют данных других объектов, запрос к базе так и останется один.
А вот в случае более сложном, если есть другие объекты, вызываемые выводимыми, и в шаблоне потребуются их параметры, при выводе добавится ещё N(=число_объектов на странице) запросов для загрузки эти подобъектов.
Борюсь с этим (если производительность так важна — дело в том, что у меня ещё часто используется статическое кеширование в *.html с автоочисткой при изменении в объектах, от которых зависит данная страница, а там хоть пять секунд генерись страница — не страшно) так.
Получив список нужных к выводу объектов в local_template_data_set() не сразу возвращаю результат, а извлекаю нужные id и получаю массив ID для загрузки вторичных объектов. И загружаю их одним запросом. Результат не использую, но объекты при этом кешируются. И потом, при выводе страницы, они будут браться уже из кеша.
Скажем, нужно вывести страницу топика форума и для каждого постинга — получить объект пользователя. Для простоты не показываю разбивку на страницы.
{foreach from=$posts as $x}
<p>{$x->create_time()|smart_time} {$x->user()->title()} пишет: {$x->body()}.</p>
{/foreach}
$x->user() в class forum_post вызовет object_load('forum_user', $this->user_id()), но нового обращения к БД уже не будет, так как все объекты уже загружены и инициализированы.
Так в этом примере в итоге получается лишь два простых запроса к БД.
1. Для наиболее ответственных обязательное предварительное тестирование на отдельной тестовой машине. Хоть на локалхосте.
2. Никакого ручного копирования. Только VCS! Раньше использовал SVN, сейчас переполз на Mercurial, для разработку в одиночку на нескольких серверах он подходит лучше.
Кстати, почти офтопик, но не заводить же новую тему…
Это только у меня Хабр сейчас немилосердно глючит в Опере? Незакрываемый диалог «Разрешённые html-теги», отсутствие появление ответа (визуально, вообще ничего не происходит). Ещё позавчера всё работало…
А какие костыли в Linux? Одно правило с HAL. Хочешь по UUID тома на флешке, хочешь по серийному её номеру… Если соответствует — разрешить, не соответствует — ничего не делать.
В таком случае Azureus'у или Eclipse'у под Linux нужен костыль в виде JVM, Tomboy или Incollector нуждаются в костыле в виде Mono, а Gajim или Quod Libet хотят в роли костыля Python :)
Именно поэтому я забросил в своё время версионные дистрибутивы.
У той же Gentoo нет понятия версии ОС. Есть только версии конкретного софта. И всё. Соответственно, нет, в принципе, обновления системы. Один раз поставил — живёт вечно. И система может погибнуть только вместе с жёстким диском :) В противном случае любой фатальный с виду глюк лечится после загрузки с LiveCD.
А что конкретно не нравится?
Понятие отдельного метода класса, который занимается данными для шаблона?
Это обычно удобнее, чем выдёргивать нужные данные из шаблона. Считаю, что работу с извлечением данных в шаблоне должна минимизироваться :)
Есть идея лучше? Давайте обсудим, тем более, что фреймворк у меня очень легко перенимает почти любые альтернативные парадигмы :)
Да, у меня используется лишнее действие. Перед отдачей данных шаблону, происходит ручная предвыборка вторичных объектов.
Кстати, эта задача легко автоматизируется. Загрузчику массива объектов можно передать параметр загрузки вторичных объектов, зависимых от загружаемых.
Мысль интересная, хотя кеширующая предвыборка у меня и занимает обычно только три коротких строки, но используется это решение часто. Можно автоматизировать.
Один — генерация объектов комментариев по тому или иному критерию.
Потом сбор ID пользователей, обычно — PHP-циклом.
Потом второй запрос — загрузка объектов пользователей. Хотя напрямую я эти объекты использовать не буду, но они закешируются. И потом, при 50 загрузках объектов этих пользователей, они будут браться не из БД, а из кеша.
Я выше этот момент описал :)
…
Можно извратиться и сделать вообще один запрос, прописав все нужные параметры пользователя прямо в объекте комментария, но это сложно, некрасиво и может привести прямо к потере производительности, т.к. на сложных БД JOIN может быть много тяжелее двух простых вызовов.
Но до того, пока понял такое поведение IE, пришлось потратить уйму времени на эксперименты. Плюс объяснение таких особенностей заказчику задним числом тоже не очень хорошо :)
— Ядро передаёт ссылку загрузчику объектов, тот грузит объект.
— Ядро вызывает метод content() и выводит результат
Загрузчик объектов:
— Находит нужный класс по его имени или по привязке форматов URL к классам.
— Создаёт объект класса.
— Инициализирует класс.
Инициализаторы классов могут быть разные. Самый популярный — это, конечно, использующий mysql-бэкенд, выполняющий ORM-маппинг. Хотя может быть и иным (часто практикую загрузку их статических *.txt, реже — XML или Oracle) или вообще отсутствовать (тоже весьма распространено).
В принципе, тут никакой отложенной загрузки нет, но я с задачей множественных обращений к БД справляюсь, используя мультизагрузку объектов и кеши.
Скажем, нужно вывести список товаров на страницу.
Объект этой страницы автоматически, при создании, ничего из БД не грузит.
Но метод content() вызовет метод local_template_data_set(), возвращающий хеш переменных для насыщения шаблона.
Вот этот метод, как раз, и может описать загрузку объектов. Например, так:
function local_template_data_set() { return array( 'list' => objects_array('my_cool_tovar', array( 'category_id' => $this->category_id(), 'is_published' => 1, 'page' => $this->page(), 'per_page' => $this->items_per_page(), 'order' => 'title', )), ); }В итоге если выводимые объекты будут автономны и не потребуют данных других объектов, запрос к базе так и останется один.
А вот в случае более сложном, если есть другие объекты, вызываемые выводимыми, и в шаблоне потребуются их параметры, при выводе добавится ещё N(=число_объектов на странице) запросов для загрузки эти подобъектов.
Борюсь с этим (если производительность так важна — дело в том, что у меня ещё часто используется статическое кеширование в *.html с автоочисткой при изменении в объектах, от которых зависит данная страница, а там хоть пять секунд генерись страница — не страшно) так.
Получив список нужных к выводу объектов в local_template_data_set() не сразу возвращаю результат, а извлекаю нужные id и получаю массив ID для загрузки вторичных объектов. И загружаю их одним запросом. Результат не использую, но объекты при этом кешируются. И потом, при выводе страницы, они будут браться уже из кеша.
Скажем, нужно вывести страницу топика форума и для каждого постинга — получить объект пользователя. Для простоты не показываю разбивку на страницы.
$posts = objects_array('forum_post', array('topic_id' => $this->id())); $user_ids = array(); foreach($posts as $p) $user_ids[$p->user_id()] = true; objects_array('forum_user', array('id' => array_keys($user_ids))); return array('posts' => $posts);В итоге в шаблоне можно сразу использовать:
{foreach from=$posts as $x} <p>{$x->create_time()|smart_time} {$x->user()->title()} пишет: {$x->body()}.</p> {/foreach}$x->user() в class forum_post вызовет object_load('forum_user', $this->user_id()), но нового обращения к БД уже не будет, так как все объекты уже загружены и инициализированы.
Так в этом примере в итоге получается лишь два простых запроса к БД.
1. Для наиболее ответственных обязательное предварительное тестирование на отдельной тестовой машине. Хоть на локалхосте.
2. Никакого ручного копирования. Только VCS! Раньше использовал SVN, сейчас переполз на Mercurial, для разработку в одиночку на нескольких серверах он подходит лучше.
Ещё сверху через раз висит незакрываемый блок «Пригласить...»
Это только у меня Хабр сейчас немилосердно глючит в Опере? Незакрываемый диалог «Разрешённые html-теги», отсутствие появление ответа (визуально, вообще ничего не происходит). Ещё позавчера всё работало…
HDD внешний подключить, если понадобится, например, p2p-сервер сделать :)
Очень громоздко :)
Плагин, hg.balancer.ru/hgwebdir/bors-core/file/1a7622f87584/engines/smarty/plugins/modifier.sklon.php:
<?php 2 function smarty_modifier_sklon($n, $s1, $s2=NULL, $s5=NULL) // 1 нож 2 ножа 5 ножей 3 { 4 if($s2 === NULL) 5 list($s1, $s2, $s5) = explode(',', $s1); 6 7 $ns=intval(substr($n,-1)); 8 $n2=intval(substr($n,-2)); 9 10 if($n2>=10 && $n2<=19) return $s5; 11 if($ns==1) return $s1; 12 if($ns>=2&&$ns<=4) return $s2; 13 return $s5; 14 }Вызывается так:
Всего в БД {$n} {$n|sklon:'сообщение':'сообщения':'сообщений'}.
Или:
Всего в БД {$n} сообщени{$n|sklon:'е':'я':'й'}.
Или:
Всего в БД {$n} сообщени{$n|sklon:'е, я, й'}.
Плюс просто функция sklon: hg.balancer.ru/hgwebdir/bors-core/file/15136adfd8fb/inc/strings.php
(да, лучше бы обозвать declension, но sklon — запомнить проще ;) )
У той же Gentoo нет понятия версии ОС. Есть только версии конкретного софта. И всё. Соответственно, нет, в принципе, обновления системы. Один раз поставил — живёт вечно. И система может погибнуть только вместе с жёстким диском :) В противном случае любой фатальный с виду глюк лечится после загрузки с LiveCD.