Comments 113
Есть «контроллер», есть «представление» со своей логикой – и тут действительно часто удобней, когда представление запрашивает данные. А шаблонизация – это сравни с темами для программ, когда реально не должно быть никакого влияние на работу программы и от того не нужны навороченные функции смарти.
Я к тому же выводу пришел, когда пытался сделать как автор…
В итоге у меня сейчас есть представления (для каждого формата своё — чтобы не получать лишних данных), а есть шаблоны (отдельно от представления), причем на нативном шаблонизаторе (читай без шаблонизатора).
Проблемы с подходом автора могут возникнуть в том, чтобы не делать лишних запросов. Можно, конечно, не делать лишних запросов в базу, но сложно будет избежать лишних запросов одних и тех же данных вообще. Ну и — слишком большая нагрузка логики на шаблоны, когда её там не должно быть вообще.
В итоге у меня сейчас есть представления (для каждого формата своё — чтобы не получать лишних данных), а есть шаблоны (отдельно от представления), причем на нативном шаблонизаторе (читай без шаблонизатора).
Проблемы с подходом автора могут возникнуть в том, чтобы не делать лишних запросов. Можно, конечно, не делать лишних запросов в базу, но сложно будет избежать лишних запросов одних и тех же данных вообще. Ну и — слишком большая нагрузка логики на шаблоны, когда её там не должно быть вообще.
вот так и появляются десятки запросов для каждой страницы…
Для этого нужно использовать кэш
какой нафиг кэш? о_0
пусть у нас выводятся список статей и список комментов, у всех у них есть авторы со своими никами, аватарами и прочими финтифлюшками.
правильная стратегия: выбрать свежие статьи, выбрать свежие комменты, собрать список всех авторов и разом выбрать их профили.
неправильная: выбирать отдельно профили для статей и отдельно для комментов.
пусть у нас выводятся список статей и список комментов, у всех у них есть авторы со своими никами, аватарами и прочими финтифлюшками.
правильная стратегия: выбрать свежие статьи, выбрать свежие комменты, собрать список всех авторов и разом выбрать их профили.
неправильная: выбирать отдельно профили для статей и отдельно для комментов.
нужно балансировать между «конструкторностью» и «узкозаточенностью».
если нужен конструктор — то view-driven рулит. если супер-мега-HL, то нужно почти с нуля писать спагетти-код конкретно под задачу.
как-то так.
если нужен конструктор — то view-driven рулит. если супер-мега-HL, то нужно почти с нуля писать спагетти-код конкретно под задачу.
как-то так.
почему на хабре все помешаны на производительности? да не пишется хайлоад так. не пишется.
это решение для средненагруженных проектов, для которых 1% потери производительности в связи с таким архитектурным решением ничего не меняет.
это решение для средненагруженных проектов, для которых 1% потери производительности в связи с таким архитектурным решением ничего не меняет.
давайте начнём с того, что использовать смарти для сайтов с высокой нагрузкой довольно стрёмное решение. есть, конечно, кэши и всё прочее, но сам по себе смарти довольно тормозной.
а на производительности все помешаны, наверное потому, что сейчас модно об этом говорить.
а на производительности все помешаны, наверное потому, что сейчас модно об этом говорить.
сейчас модно говорить, но 99% говорящих о к HL никаким боком не относится, всё сводится к софистике и мыслям, без практики и доступа к настоящим нагруженным проектам. это первое.
второе — я и не говорил о том, что смарти клёвое решение для HL. смарти — хороший шаблонизатор для средненагруженных проектов.
mzz, который сам по себе сейчас очень небыстрый, вкупе со смарти на десктопной машине удалось выжать около 30req/s на типичной странице типичного сайта. это много? это мало? при равномерной загрузке — это 2.5М хитов в день.
этого хватит пресловутым 99% обсуждающим хайлоад, а оставшиеся 1% в подобные споры не лезут и спокойно хихикают в сторонке.
второе — я и не говорил о том, что смарти клёвое решение для HL. смарти — хороший шаблонизатор для средненагруженных проектов.
mzz, который сам по себе сейчас очень небыстрый, вкупе со смарти на десктопной машине удалось выжать около 30req/s на типичной странице типичного сайта. это много? это мало? при равномерной загрузке — это 2.5М хитов в день.
этого хватит пресловутым 99% обсуждающим хайлоад, а оставшиеся 1% в подобные споры не лезут и спокойно хихикают в сторонке.
На самом деле зачастую смарти — далеко не самое узкое место в HL. Им всегда будет БД в первую очередь.
а почему он должен работаь дольше? думаю примерно столько же
с одной стороны понимаю что «управляющее представление» бывает иногда удобным и логичным в использовании.
с другой стороны, остается чувство «неправильности» такого подхода.
поясню что именно меня смущает:
— получается что тот кто делает шаблоны, тот и управляет приложением. зачастую за шаблоны отвечает верстальщик. получается что он может вызывать из шаблона те данные которые ему заблагорассудится, не думая о том что это может вызвать повторные выборки или что эти данные в данном блоке вообще нельзя отображать…
— если нам нужно в процессе работы скрипта сделать чтото в без вывода в шаблон (статистику подсчитать, обновить чтонить в Бд) то мы все равно в шаблоне должны прописать вызов соответсвующего блока, даже зная что он ничего не выдаст на выход? и потом глядя на код шаблона попробуй пойми где есть вывод в шаблон а где нет.
-что с безопасностью данных? кто будет решать какой шаблон имеет право получать данные которые он запросил или нет?
с другой стороны, остается чувство «неправильности» такого подхода.
поясню что именно меня смущает:
— получается что тот кто делает шаблоны, тот и управляет приложением. зачастую за шаблоны отвечает верстальщик. получается что он может вызывать из шаблона те данные которые ему заблагорассудится, не думая о том что это может вызвать повторные выборки или что эти данные в данном блоке вообще нельзя отображать…
— если нам нужно в процессе работы скрипта сделать чтото в без вывода в шаблон (статистику подсчитать, обновить чтонить в Бд) то мы все равно в шаблоне должны прописать вызов соответсвующего блока, даже зная что он ничего не выдаст на выход? и потом глядя на код шаблона попробуй пойми где есть вывод в шаблон а где нет.
-что с безопасностью данных? кто будет решать какой шаблон имеет право получать данные которые он запросил или нет?
(альтернативное решение, исключающее проблемы с безопасностью из последнего пункта)
мы в нашем фреймворке (чтобы не рекламить — просто сошлюсь на свой профиль) пошли чуток дальше, и загружаем в шаблон целые действия, а не данные:
{load module=«comments» action=«list» id=666}
соответственно авторизация осуществляется системным acl.
мы в нашем фреймворке (чтобы не рекламить — просто сошлюсь на свой профиль) пошли чуток дальше, и загружаем в шаблон целые действия, а не данные:
{load module=«comments» action=«list» id=666}
соответственно авторизация осуществляется системным acl.
что значит «загружаем действия»?
вызовется действие которое подготовит данные, скормит шаблонизатору и вернет готовый html-блок?
или вызовется шаблон данного действия, который уже сам себя сформирует и то что он вернет и будет искомым блоком?
вызовется действие которое подготовит данные, скормит шаблонизатору и вернет готовый html-блок?
или вызовется шаблон данного действия, который уже сам себя сформирует и то что он вернет и будет искомым блоком?
{load module=«comments» action=«list» id=666}
неужели эта строка не релевантна? :-)
будет вызван модуль комментариев с действием list (список комментариев). всё это глубоко внутри сгенерит в html и он результатом будет вставлен в это место.
неужели эта строка не релевантна? :-)
будет вызван модуль комментариев с действием list (список комментариев). всё это глубоко внутри сгенерит в html и он результатом будет вставлен в это место.
строку вызова модуля я осознал)
вопрос был про метод генерации html.
исходя из ваших слов получается что модуль генерит html «глубоко внутри» себя. не используя шаблонизатор?
тогда непонятно почему не используя.
если успользуете внутри модуля шаблонизатор, то получается что у вас смешанная логика — то управление в руках представления то в руках контроллера модуля…
не скажу что это плохо. но както странно)
вопрос был про метод генерации html.
исходя из ваших слов получается что модуль генерит html «глубоко внутри» себя. не используя шаблонизатор?
тогда непонятно почему не используя.
если успользуете внутри модуля шаблонизатор, то получается что у вас смешанная логика — то управление в руках представления то в руках контроллера модуля…
не скажу что это плохо. но както странно)
используя шаблонизатор, конечно же.
чтобы быть более корректным: {load… вызывает контроллер приложения. в данном случае: commentsListController. как генерит этот контроллер контент — исключительно его проблемы. опять же, в данном случае, конечно же, используется конкретный шаблон для отрисовки списка комментариев.
чтобы быть более корректным: {load… вызывает контроллер приложения. в данном случае: commentsListController. как генерит этот контроллер контент — исключительно его проблемы. опять же, в данном случае, конечно же, используется конкретный шаблон для отрисовки списка комментариев.
понятно.
можете выделить четкие преимущества вашего подхода?
можете выделить четкие преимущества вашего подхода?
модульность.
при достаточном опыте, фанатизме и прочем-прочем-прочем может получиться весьма интересный комбайн, в котором комментируемость сущности достигается добавлением вышеуказанной строки в шаблон отображения сущности.
таким образом, добавляя по 1 (в общем случае) строке в шаблон «новости» мы можем её сделать: с комментариями, с рейтингом, с тегами,…
при некотором незначительном оверхеде (а то сейчас набегут фанаты хайлоада) мы получаем очень реюзабельный набор компонент.
при достаточном опыте, фанатизме и прочем-прочем-прочем может получиться весьма интересный комбайн, в котором комментируемость сущности достигается добавлением вышеуказанной строки в шаблон отображения сущности.
таким образом, добавляя по 1 (в общем случае) строке в шаблон «новости» мы можем её сделать: с комментариями, с рейтингом, с тегами,…
при некотором незначительном оверхеде (а то сейчас набегут фанаты хайлоада) мы получаем очень реюзабельный набор компонент.
хм. интересно. надо будет подумать на досуге о том что вы сказали )
можете даже код посмотреть :-)
посмотрю.
но если пойти еще дальше. то можно вообще уйти от контролеров ))
ведь по сути, если представление само дергает нужные ему данные, то оно само и решения принимать, и в случае чего дергать нужные системные действия…
хотя это уже полная поломка mvc
но если пойти еще дальше. то можно вообще уйти от контролеров ))
ведь по сути, если представление само дергает нужные ему данные, то оно само и решения принимать, и в случае чего дергать нужные системные действия…
хотя это уже полная поломка mvc
представление не дёргает данные. представление лишь запускает механизм получения-обработки-возврата информации.
В ZF это делается так framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.action
И вот что написано в performance guide framework.zend.com/manual/en/performance.view.html#performance.view.action
И вот что написано в performance guide framework.zend.com/manual/en/performance.view.html#performance.view.action
у меня именно такая система в фреймворке получилась — очень удобно выставлять в счёт 2 дня разработки, а делать это одной строчкой в шаблоне
ps: представление в руках шаблонизатора: шаблон является активной составляющей, которая запрашивает результат выполнения некоторой операции. контроллер — работает лишь тогда, когда его запрашивает шаблон. естественно, что шаблон, который будет использоваться для отрисовки результатов работы контроллера, в свою очередь, также может содержать вызовы других методов (рекурсия). т.е. шаблон так и остаётся активным компонентом, контроллер — пассивным.
ну, я просто пример привёл. у меня немного сложнее там всё =)
я честно пошел в «просто сошлюсь на свой профиль» и ничего там не нашел. ткните меня пожалуйста, куда смотреть?
вы ж наверняка понимаете, что поднятые вами вопросы легко и непринуждённо решаются кучей способов, в том числе вообще административных.
кроме того, я предлагаю способ расширения функциональности смарти, а не какую-то смену парадигмы. всё так же можно использовать ведущие кнотроллеры или смешанный подход.
лучше же когда есть возможность, чем когда её нет, правда? =)
кроме того, я предлагаю способ расширения функциональности смарти, а не какую-то смену парадигмы. всё так же можно использовать ведущие кнотроллеры или смешанный подход.
лучше же когда есть возможность, чем когда её нет, правда? =)
Прикольное решение ++
Я, правда, лет 5 назад выбрал другой путь:
— Контроллер даёт Smarty базовые данные (например список постов для блога)
— В самом шаблоне дизайнер можно «пропросить ещё» с помощью узконаправленных функция с параметрами, например захотелось мне список ссылок на все посты в календарике — пишу {load_calendar month=$month foo=bar bla=foo} — а со стороны смарти есть плагин, который запрашивает у БД эти данные и там же делаеть $smarty->assign… естественно всё это щастя можно обрамить блоком {cache}{/cache} и запрашиваться эти данные будут всего, например, раз в сутки :)
Я, правда, лет 5 назад выбрал другой путь:
— Контроллер даёт Smarty базовые данные (например список постов для блога)
— В самом шаблоне дизайнер можно «пропросить ещё» с помощью узконаправленных функция с параметрами, например захотелось мне список ссылок на все посты в календарике — пишу {load_calendar month=$month foo=bar bla=foo} — а со стороны смарти есть плагин, который запрашивает у БД эти данные и там же делаеть $smarty->assign… естественно всё это щастя можно обрамить блоком {cache}{/cache} и запрашиваться эти данные будут всего, например, раз в сутки :)
Делаю аналогично. index.php у меня выбирает список шаблонов, которые нужно проинклудить в контейнер и некоторые базовые данные (заголовок страницы, язык и прочее), а всё остальное реализуется плагинами.
Фигасе, меня Clops коментит =)
Собственно, никакая другая функциональность смарти не отменяется же. Всё можно использовать по-старому, но теперь добавляется возможность ещё и из представления данные просить.
И, да, {cache} рулит и бибикает.
Собственно, никакая другая функциональность смарти не отменяется же. Всё можно использовать по-старому, но теперь добавляется возможность ещё и из представления данные просить.
И, да, {cache} рулит и бибикает.
;)
вообще я когда-то пришёл к такой же иделогии как и zerkms выше habrahabr.ru/blogs/php/60561/#comment_1654271
ведь в итоге НАМ главное за минимальные сроки заработать как можно больше :)
вообще я когда-то пришёл к такой же иделогии как и zerkms выше habrahabr.ru/blogs/php/60561/#comment_1654271
ведь в итоге НАМ главное за минимальные сроки заработать как можно больше :)
Я вот до сих пор не пойму, чем не угодил разработчиком нативный PHP для шаблонов? Не уже ли так сложно написать <?=$variable ?>, вместо {$variable}
И всё остальное не так уж и сложно. И циклы тебе есть, и управляющие структуры и всё остальное. А все эти шаблонизаторы новые мало того что свой синтаксис имеют, да еще и оверхед создают. Ужас, порой смотришь «скомпилированный» код и диву даешься, а потом и возникает вопрос, вообще зачем нужен этот шаблонный движок.
И всё остальное не так уж и сложно. И циклы тебе есть, и управляющие структуры и всё остальное. А все эти шаблонизаторы новые мало того что свой синтаксис имеют, да еще и оверхед создают. Ужас, порой смотришь «скомпилированный» код и диву даешься, а потом и возникает вопрос, вообще зачем нужен этот шаблонный движок.
не разводите холивар на тему шаблонизаторов тут, пожалуйста.
тема топика здесь немного иная.
тема топика здесь немного иная.
Здесь говорят про шаблонизаторы? Да, вот я и высказываю свое отношение к ним, если тебе не интересно, то никто не заставляет тебя читать это.
здесь говорят о конкретной технике использования конкретного шаблонизатора.
целесообразность его использования — тема для другого топика. напишите — вот так и пофлудим.
целесообразность его использования — тема для другого топика. напишите — вот так и пофлудим.
Да я вообще про шаблонизаторы говорю, а не про конкретный движок. Smarty он еще ничего, насколько я помню, судя по его скопилированным шаблонам и скорости.
Просто бывает приходится использовать CMS, где нет выбора шаблонизатор/нативный PHP для шаблонов.
Просто бывает приходится использовать CMS, где нет выбора шаблонизатор/нативный PHP для шаблонов.
Вот наглядный пример «скомпилированного» шаблона :) Особенно смешит комментарий в коде «foreach begins :)
// foreach begins
$skipDelimiter = true;
if ( !isset( $fe_variable_stack_9f2394a2ee3ad41eca845f69ff884b58_8 ) ) $fe_variable_stack_9f2394a2ee3ad41eca845f69ff884b58_8 = array();
$fe_variable_stack_9f2394a2ee3ad41eca845f69ff884b58_8[] = compact( 'fe_array_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_array_keys_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_n_items_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_n_items_processed_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_i_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_key_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_val_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_offset_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_max_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_reverse_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_first_val_9f2394a2ee3ad41eca845f69ff884b58_8', 'fe_last_val_9f2394a2ee3ad41eca845f69ff884b58_8' );
unset( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 );
unset( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 );
$fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 = ( array_key_exists( $rootNamespace, $vars ) and array_key_exists( 'last_topics', $vars[$rootNamespace] ) ) ? $vars[$rootNamespace]['last_topics'] : null;
if (! isset( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 ) ) $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 = NULL;
while ( is_object( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 ) and method_exists( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8, 'templateValue' ) )
$fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 = $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8->templateValue();
$fe_array_keys_9f2394a2ee3ad41eca845f69ff884b58_8 = is_array( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 ) ? array_keys( $fe_array_9f2394a2ee3ad41eca845f69ff884b58_8 ) : array();
$fe_n_items_9f2394a2ee3ad41eca845f69ff884b58_8 = count( $fe_array_keys_9f2394a2ee3ad41eca845f69ff884b58_8 );
$fe_n_items_processed_9f2394a2ee3ad41eca845f69ff884b58_8 = 0;
$fe_offset_9f2394a2ee3ad41eca845f69ff884b58_8 = 0;
$fe_max_9f2394a2ee3ad41eca845f69ff884b58_8 = $fe_n_items_9f2394a2ee3ad41eca845f69ff884b58_8 - $fe_offset_9f2394a2ee3ad41eca845f69ff884b58_8;
$fe_reverse_9f2394a2ee3ad41eca845f69ff884b58_8 = false;
* This source code was highlighted with Source Code Highlighter.
O_o
хардкорный шаблон
хардкорный шаблон
Пример кстати реальный абсолютно. Не с потолка взят. Мне даже трудно представить какую логику выполняет этот кусок. А вот так выглядит шаблон, который был скомпилирован в это «чудо»
{def $last_topics = fetch( 'content', 'list',
hash( 'parent_node_id', ezini( 'SourceContentObjects', 'ForumRSSFeed', 'block_settings.ini'),
'depth', 1,
'limit', 5,
'sort_by', array( 'published', false() ),
) )
}
<div class=«column_block» id=«block_forum»>
<div class=«head»>
<div class=«tab»>
<div class=«tl»></div>
<h2>Форум</h2>
<div class=«tr»></div>
</div>
</div>
<div class=«content»>
<p>Последние темы:</p>
<ol>
{foreach $last_topics as $topic}
<li><a href={$topic.object.data_map.link.value|ezurl}>{$topic.name|wash}</a></li>
{/foreach}
</ol>
<div class=«ref»><a href={"/forum/"|ezurl}><img src={«images/go.png»|ezdesign} class=«png» alt=«Перейти» width=«11» height=«11» /><span>Все обсуждения</span></a></div>
</div>
</div>
* This source code was highlighted with Source Code Highlighter.
P.S. А некоторым товарищам спасибо, за подпорченные остатки кармы)
{def $last_topics = fetch( 'content', 'list',
hash( 'parent_node_id', ezini( 'SourceContentObjects', 'ForumRSSFeed', 'block_settings.ini'),
'depth', 1,
'limit', 5,
'sort_by', array( 'published', false() ),
) )
}
<div class=«column_block» id=«block_forum»>
<div class=«head»>
<div class=«tab»>
<div class=«tl»></div>
<h2>Форум</h2>
<div class=«tr»></div>
</div>
</div>
<div class=«content»>
<p>Последние темы:</p>
<ol>
{foreach $last_topics as $topic}
<li><a href={$topic.object.data_map.link.value|ezurl}>{$topic.name|wash}</a></li>
{/foreach}
</ol>
<div class=«ref»><a href={"/forum/"|ezurl}><img src={«images/go.png»|ezdesign} class=«png» alt=«Перейти» width=«11» height=«11» /><span>Все обсуждения</span></a></div>
</div>
</div>
* This source code was highlighted with Source Code Highlighter.
P.S. А некоторым товарищам спасибо, за подпорченные остатки кармы)
чета неверится что смарти сгенерил «такое» ))
я сколько раз видел скомпиленные им шаблоны, там было не так страшно
я сколько раз видел скомпиленные им шаблоны, там было не так страшно
давайте холивар моде офф.
у меня (как и у дефолтного пхп) отключены шорт-таги, поэтому такая конструкция вообще не сработает.
называть же смарти новым шаблонизатором это клёво. тем не менее, почитайте его документацию, если ещё не.
у меня (как и у дефолтного пхп) отключены шорт-таги, поэтому такая конструкция вообще не сработает.
называть же смарти новым шаблонизатором это клёво. тем не менее, почитайте его документацию, если ещё не.
А зачем столько писанины, если можно создать свою функцию в папке smarty\plugins?
добавляем туда файл function.data.php
в котором объявляем
и получаем всё тоже самое насколько я понял )
добавляем туда файл function.data.php
в котором объявляем
function smarty_function_data($params, &$smarty) { return 'Hello World'; }
и получаем всё тоже самое насколько я понял )
Если на один проект один экземпляр дистрибутива смарти то да, (как в штатах, одна война — один рейнджер =) а если модуль смарти разделяемый скажем между десятком проектов со стандартными разделяемыми плагинами которые к примеру гребут данные из некой ядровой БД? Тут либо префиксовать либо сходить с ума от перекрытий если каждый разработчик туда по своей поделке развесит. Плюс деплоить не сильно удобно.
директорий плагинов в смарти может быть не одна.
Согласен, случаи бывают разные.
Я просто в качестве примера привел более лёгкий вариант, ибо с такими случаями о которых вы говорите, пока слава богу не сталкивался )
Я просто в качестве примера привел более лёгкий вариант, ибо с такими случаями о которых вы говорите, пока слава богу не сталкивался )
Как надо пользоваться смарти
class mySmarty extends Smarty{
public function __construct(){
//тут оверрайдим все дефольные настройки смарти
//во все пути можно так же фигачить массивы, они будут обрабатываться по-очереди пока там не будет найдек нужный файл
//ejoy
}
}
class mySmarty extends Smarty{
public function __construct(){
//тут оверрайдим все дефольные настройки смарти
//во все пути можно так же фигачить массивы, они будут обрабатываться по-очереди пока там не будет найдек нужный файл
//ejoy
}
}
зачем наследоваться, когда достаточно для этого конкретно случая определить функцию getSmarty где всё будет инициализироваться в штатном порядке.
вспоминаю BASIC из 5го класса — было круто! а ещё там была команда «goto». вам наверное её в php не хватает?
куда-то вас не туда понесло.
перечитайте мой комментарий вдумчиво… в голове не всплывают термины вроде The Singleton Pattern, The Abstract Factory Pattern. не?
перечитайте мой комментарий вдумчиво… в голове не всплывают термины вроде The Singleton Pattern, The Abstract Factory Pattern. не?
потому что функциональное программирование — зло, но это уже тема для отдельного топика
каким боком тут функциональное программирование?
это обычный синглтон/фабрика/билдер.
это обычный синглтон/фабрика/билдер.
в моём понимании фабрика работает вот так:
$smarty = $myFactory->cast('smarty',[arg1,[arg2],[argn]]);
внутри фабрика подгрузит библиотеку и передаст в её конструктор все аргументы, а потом просто вернёт указатель на свежий объект
если же использовать для этого дела «stand-alone» функции, то с того момента, когда на проекте будет сидеть 30 девелоперов и 2 000 000 строк кода — то каждого нового члена команды будете обучать по несколько месяцев ну и так далее в этом же духе :)
лучще всё делать на объектах и полностью инкапсулировать их действия
$smarty = $myFactory->cast('smarty',[arg1,[arg2],[argn]]);
внутри фабрика подгрузит библиотеку и передаст в её конструктор все аргументы, а потом просто вернёт указатель на свежий объект
если же использовать для этого дела «stand-alone» функции, то с того момента, когда на проекте будет сидеть 30 девелоперов и 2 000 000 строк кода — то каждого нового члена команды будете обучать по несколько месяцев ну и так далее в этом же духе :)
лучще всё делать на объектах и полностью инкапсулировать их действия
да какая разница — будет это функция или метод объекта. я к тому — что процесс построения объекта можно (нужно!) инкапсулировать в отдельном методе/функции. и что это будет куда более академичным вариантом, чем наследование.
ps: ваше понимание фабрики немного размыто, насколько я смог понять из сниппета кода и описания работы этого кода.
ps: ваше понимание фабрики немного размыто, насколько я смог понять из сниппета кода и описания работы этого кода.
чтобы полностью быть уверенным, что вы меня понимаете — вот вам код: govnokod.com/993
первое правило OOP — никогда не трогать значения переменных снаружи объекта напрямую
$object->foo = 'bar'; //epic fail
$object->setFoo('bar'); //will survive
$object->foo = 'bar'; //epic fail
$object->setFoo('bar'); //will survive
хоть я и в своей практике в своих классах никогда не открываю свойства в public, но всё таки хотел бы увидеть пруфлинк на это самое правило.
касаемо смарти — ничего криминального не вижу. это сторонняя библиотека, её писал другой человек — его дело как он предоставляет доступ к конфигурации. я этого не одобряю, но так решил он (а вообще причина в BC)
ps: своим наследованием вы ни капли не делаете решение более OOP-way'ным — все свойства у вас так и остаются публичными и вполне могут быть изменены намеренно/случайно в рантайме.
касаемо смарти — ничего криминального не вижу. это сторонняя библиотека, её писал другой человек — его дело как он предоставляет доступ к конфигурации. я этого не одобряю, но так решил он (а вообще причина в BC)
ps: своим наследованием вы ни капли не делаете решение более OOP-way'ным — все свойства у вас так и остаются публичными и вполне могут быть изменены намеренно/случайно в рантайме.
то, что они там публичные — это историческая «проблема», чтобы новые версии Smarty работали в PHP4 :(
а вообще, в первой же главе оф.мануала рекомендуют наследовать класс
smarty.net/manual/en/installing.smarty.extended.php
относительно геттеров и сеттеров — довольно много ошибок в приложениях именно из-за того что кто-то в команде разработчиков где-то в коде присваивает свои значения переменным объекта, а где-то в другом месте всё начинает косячить несмотря на то, что все assertions ведут себя хорошо… используя getters && setters можно быстро получить весь стек значений, найти место в коде где безобразничали и надругаться над обидчиком.
Простите, наболело :)
а вообще, в первой же главе оф.мануала рекомендуют наследовать класс
smarty.net/manual/en/installing.smarty.extended.php
относительно геттеров и сеттеров — довольно много ошибок в приложениях именно из-за того что кто-то в команде разработчиков где-то в коде присваивает свои значения переменным объекта, а где-то в другом месте всё начинает косячить несмотря на то, что все assertions ведут себя хорошо… используя getters && setters можно быстро получить весь стек значений, найти место в коде где безобразничали и надругаться над обидчиком.
Простите, наболело :)
я же сказал — что я тоже против публичного доступа. но называть бы это «первым правилом OOP» я бы побоялся.
по поводу совета из мануала: ну и что, что они так советуют :-) Монте вообще очень странный человек с очень странной позицией.
в этом вопросе я (и OOP-практики) с ним не соглашусь — это не место и не повод для наследования. для создания и начальной «настройки» объектов есть синглтоны и билдеры.
по поводу совета из мануала: ну и что, что они так советуют :-) Монте вообще очень странный человек с очень странной позицией.
в этом вопросе я (и OOP-практики) с ним не соглашусь — это не место и не повод для наследования. для создания и начальной «настройки» объектов есть синглтоны и билдеры.
бред :(
Сам вопрос очень спорный про использование геттеров и сеттеров. А подобная безапелляционность — это бред.
Сам вопрос очень спорный про использование геттеров и сеттеров. А подобная безапелляционность — это бред.
а для чего тогда были придуманы properties?
которые предоставляют синтаксис обычных полей класса, при этом имеют геттеры и сеттеры за спиной
которые предоставляют синтаксис обычных полей класса, при этом имеют геттеры и сеттеры за спиной
правильно понимаю, что мы сейчас про ООП вообще? ну так совсем не во всех языках реализованы свойства.
в том же php их нет и нужно выкручиваться через переопределение __get и __set. а если логика не смая тривиальная то там такая каша получается, что лучше сделать отдельные методы.
так что ваша реплика слегка непонятна.
в том же php их нет и нужно выкручиваться через переопределение __get и __set. а если логика не смая тривиальная то там такая каша получается, что лучше сделать отдельные методы.
так что ваша реплика слегка непонятна.
Затем чтобы переопределить штатный фетч например :)
Но вообще конечно, проъачить вызов гетсмарти заменой на наследование дело на 20 минут.
Я тож привык наследовать. Это плохо чем-то?
Но вообще конечно, проъачить вызов гетсмарти заменой на наследование дело на 20 минут.
Я тож привык наследовать. Это плохо чем-то?
в случае переопределения метода — согласен. наследоваться, чтобы изменять конфигурацию в конструкторе, для изменения которой, между прочим, есть штатные средства — бредово. не правда ли?
штатные средства — какие например? я не видел у Smarty ни getter ни setter functions, более того, в конструкторе можно сделать ещё много чего полезного, оттуда и название — «конструктор» :)
Ну об этом разговора вообще нет :) Конечно.
штатный fetch я переопределяю в 100% случаев — типа сначала отдать smarty все «стандартные» переменные (типа путей и прочей херни), а потом уже вызывать родительский
можно чуток поподробнее? зачем пути и прочие «стандартные переменные» каждый раз отдавать смарти перед фетчем?
их установка осуществляется единожды, после создания объекта смарти.
их установка осуществляется единожды, после создания объекта смарти.
пардон — переопределяю display — он уже вызывается единожды
всё равно мысль не понял :-)
ну что-то из серии
public function display($template,$cacheID){
$this->assignDefaultVariables();
//...other userful stuff b4 display
return parent::display($template,$cacheID);
}
само приложение для генерации любой отдельно взятой страницы в любом случае вызовет только один раз display =)
public function display($template,$cacheID){
$this->assignDefaultVariables();
//...other userful stuff b4 display
return parent::display($template,$cacheID);
}
само приложение для генерации любой отдельно взятой страницы в любом случае вызовет только один раз display =)
волшебный код, волшебный! :-)))))))
HA-HA!
а кто вам сказал что display() будет вызван единожды?
в моём коде не бывает иначе — не вижу смысла делать это больше одного раза на страницу
display() вызывается в конце, когда уже нужно отображать результат, ведь так?
а до этого, пока работает контроллер или модель, происходит assign() или fetch() для перекеширования или подготовки блоков каких нибудь…
для этого нужно чтоб ваш $this->assignDefaultVariables(); УЖЕ был вызван
а вы его только в display() вызываете
странно, не правда ли?
а до этого, пока работает контроллер или модель, происходит assign() или fetch() для перекеширования или подготовки блоков каких нибудь…
для этого нужно чтоб ваш $this->assignDefaultVariables(); УЖЕ был вызван
а вы его только в display() вызываете
странно, не правда ли?
нет не странно — fetch в коде вызываю только для компиляции писем — там переменные окружения не нужны. все «подготовки блоков» и прочая фигня происходит в шаблоне с помощью плагинов смарти, на этот момент он уже получил все «стандартные» значения
ваше право конечно.
но не понимаю почему вы игнорируете Конструктор, его для таких задач и придумали — инициализировать окружение объекта и т.д.
но не понимаю почему вы игнорируете Конструктор, его для таких задач и придумали — инициализировать окружение объекта и т.д.
проблема в том, кто на момент создания смарти у меня порой ещё «далеко не всё известно» :)
но вы согласны, что _нужно_ использовать конструктор? а то несколько выше меня в этом пытались разубедить
но вы согласны, что _нужно_ использовать конструктор? а то несколько выше меня в этом пытались разубедить
>«далеко не всё известно» :)
что там у вас за мутант-смарти которому столько всего нужно знать )
я в таких случаях делаю ЭТО в конструкторе — и не парюсь )
что там у вас за мутант-смарти которому столько всего нужно знать )
я в таких случаях делаю ЭТО в конструкторе — и не парюсь )
смарти в порядке — просто, например, я ему сообщаю кол-во запросов сделаных к базе, сколько расходовалось памяти, что было найдето в кеше а что нет — банальная статистика
аналогично пользуюсь подобной статистикой, но у меня все просто:
объекты DB и Cache сами подсчитывают запросы и попадания в кеш…
а в шаблонизаторе, в нужном мне месте, я просто получаю из этих объектов что мне нужно: количество или сам текст запросов. и отображаю эту инфу как мне надо. шаблонизатору ничего и никого ждать не надо.
Он вообще абстрагирован, и ничего не знает о том откуда получил данные и т.д.
соотвественно его можно использовать всегда и везде, так как количество зависимостей сведено к минимуму.
объекты DB и Cache сами подсчитывают запросы и попадания в кеш…
а в шаблонизаторе, в нужном мне месте, я просто получаю из этих объектов что мне нужно: количество или сам текст запросов. и отображаю эту инфу как мне надо. шаблонизатору ничего и никого ждать не надо.
Он вообще абстрагирован, и ничего не знает о том откуда получил данные и т.д.
соотвественно его можно использовать всегда и везде, так как количество зависимостей сведено к минимуму.
Была задача не только сделать плагин-функцию к смарти, но и «подружить» её с моим окружением. То есть, она должна спокойно работать в двух предметных областях — проектной и смарти. И вместо того, чтобы городить потом получение необходимых для работы ссылок я решил дать смарти указатель на метод объекта, уже находящегося в предметной области проекта.
Кстати, Дмитрий Котеров такой (или почти такой) подход назвал «Компонентный». Это вроде как дальнейшая реализация MVC
Да, удобно использовать эти самые компоненты в дополнении к модели «ведущий контроллер», например чтобы рисовать юзерпики и т.п.
На странице www.phpwact.org/pattern/template_view описаны некоторые архитектурные подходы для построения View с ипользованием шаблонов.
Можно пойти еще дальше к сервисно-ориентированной архитектуре. А вместо smarty который живет внутри одного процесса использовать SSI или какой-либо более продвинутый front-end шаблонизатор. Получаем неплохое масштабирование.
уже давно пользуюсь таким методом, лично мне очень нравится такой подход
офтоп: smarty.net как всегда лежит, поделитесь мануальчиком в pdf или зеркалом
Sign up to leave a comment.
Smarty в управляемой представлениями модели