Comments 135
В оригинальной статье допущена ошибка. Этот код:
public function getLatestBlogs($limit = null)
{
$qb = $this->createQueryBuilder('b')
->select('b, c')
->leftJoin('b.comments', 'c')
->addOrderBy('b.created', 'DESC');
if (false === is_null($limit))
$qb->setMaxResults($limit);
return $qb->getQuery()
->getResult();
}
не будет корректно возвращать посты при заданном лимите, из-за того что к таблице постов джойнятся комментарии.
Точно! Распространённые грабли, в том числе среди не новичков. Поясню для тех, кто знакомится с ними впервые: чтобы получить то, что требуется ($limit блогов с комментариями), нужно сначала (отдельным запросом) выбрать айдишники нужных блогов в количестве $limit штук, а потом (вторым запросом) выбрать блоги, комментарии к ним и всё что ещё потребуется, используя ->andWhere('b.id IN :blogs_ids')
, при этом не используя ни setMaxResults
, ни всякие andWhere
. Бандл knp_paginator
берёт эту рутину на себя, его можно использовать не только для пагинации.
http://blog.kpitv.net/article/frameworks-1/
:)
Бред какой-то по ссылке. Даже комментировать не хочется. Не знаю кто автор, но это у него в голове сплошные дырявые абстракции.
продолжаете размахивать пиписькой? Прекращайте. В предыдущей части вы уже порядком показали что плаваете в вопросах практической реализации современных фреймворков. Иначе говоря ваши аргументы устарели.
поделитесь пожалуйста примером как это красиво реализовать на симфони именно для ситуации когда нужно вывести несколько постов с лимитом, и комментарии к ним. В Yii2 есть магический метод with(), а в doctrine пока ничего подобного не нашел(возможно и не найду?)
То есть, для того, чтобы показать количество комментов, нужно выбирать все комменты?
Гениально.
>Так как теги хранятся в базе данных в виде значений, разделенных запятыми
Явно нужна нормализация базы…
>if (false === is_null($limit))
Странное условие
>Гораздо лучший подход будет заключаться в том, чтобы отображать не дату, а время, которое прошло с момента публикации комментария
Очень спорно.
П.С.
Но все равно спасибо за руководство, так как скоро придется с этим чудом работать.
Нужно думать, что лениво грузить.
Грузить все комменты для показа количества не нужно ни лениво, ни нелениво.
Гении фреймворков собрались, блин.
прямо сериал.
а могли просто поставить wordpress
Сам когда-то знакомился с Django, на подобном материале, хотя и не написал в итоге ни одного блога :)
но wordpress покрывает 90% или более реальных задач из работы «Что-то типо web студии».
если б этот чудо фрймворк sympony показали на примере для чего то более серъезного — типа написания своего фейсбука. или гугола
я б дейсвительно задумался о его применении.
а так больше похоже на попытку усложнить и повысить стоимость разработки типовых задач. но зачем? если с этим справитс wordpress.
Надо понимать, что написание фейсбука не зависит от фреймворка, поскольку 99,99999% кода к фреймворку отношения иметь не будет. А оставшиеся 0.00001% — реализуются на любом фреймворке одинаково.
Разжуйте, пожалуйста, свою аналогию, а то она не совсем понятна и очевидна. :)
>поскольку 99,99999% кода к фреймворку отношения иметь не будет.
Поскольку в здравом уме никто такой проект не будет писать на мейнстримовом фреймворке. Хотя фейсбук те еще клоуны.
Фейсбук на самописи?
и вот тут то мы и приходим к заключению — что фреймворки бесполезны.
Плюс фреймворки все-таки написаны людьми, прочитавшими «пару» книжек по проектированию приложений в отличии от людей, познающим мир фреймворков на примере 2008 года.
да и пробелма не в количестве пользователей, а в соотношении инфраструктурного кода и бизнес логики. когда инфраструктура лишь незначительный процент, то имеет смысл пилить её с нуля под себя. если вся бизнес логика — банальный круд, то смысл делать его руками, если фреймворк его генерит на автомате со схемы бд?
Признаюсь честно, не участвовал в проекте хотя бы на пару тысяч пользователей, где были бы тупо круды.
железо дешевое, разработка дорогая.
Как только дело начинает касаться денег, вы отказываетесь от шардинга и начинаете использовать мощные мешалки в HA или инструменты типа RAC. Машины под это дело довольно дорогие, и если есть возможность оптимизировать — необходимо оптимизировать. В недалеком прошлом закупал 8 сокетную конфигурацию о 64 ядрах в 2х экземплярах + хд + сеть. Мне бы, думаю, на (остаток жизни)x2 хватило бы. И это на x86.
На новой работе раз в 2-3 месяца приходится вбивать костыли. Да архитектура не ахти. От изначального ядра и фреймворка мало что осталось в процессе.
Я работал на PHP только с Yii и CodeIgniter.
Готовое решение в разы трудней кастомизировать
Не повторяйтесь, я не спорю с этим утверждением.
Самопись на порядки медленней в старте
Моя работа не связанна со стартапами. Заказчику в итоге необходимо законченное решение, а не 20% для старта. Если нужно очень быстро стартануть, возьмите битрикс.
тоже хороший пример бесполезности фрейморков.
wordpress.com пользуются милионы пользователей, там используется WordPress — который составляет не каплю в море, а именно что основу.
так же отсюда следует что WordPress вполне годится для высоконагруженных проектов.
> Тогда да, проще запилить собственный фреймворк идеально подогнаный конкретно под ваш проект. но это тоже компромис
> и сделать это можно лишь имея нормальный бюджет на разработку и время.
если сразу решать задачу на готовом инструменте, а не пилить свой фрейморк то и время и бюджет станет намного меньше.
PHP это специализированный язык для веб — поставляется с большим кол-вом функций из коробки.
Фреймворки всеголишь оборачивают всю имеющуюся функциональность в кривые абстракции
и не предоставлют никаких конкретных инструментов для решения задач.
данные абстракции в специализированных языках и не нужны вовсе (в PHP они как собаке пятая нога)
(они нужны лишь в языках типа C++ чтобы скрыть всю кривость данного языка и облегчить за счет этих костыльных абстракций программирование),
непойму нах* это все нужно — если можно через PDO запросы фигачить, ну максимум написать свой кверибилдер для сохранения загрузки объектов/массивов в десяток срок кода и выводить данные встроеным в php шаблонизатором,
сохранять каждый экшн в файл. выделять основные функции в автоматически подгружаемые классы.
использовать роутинг apache или nginx.
я уже говорил выше что php не голый язык общего назначения, чтоб поверх него была необходимость городить якобы «удобные» абстракции
там уже из коробки все нужное есть.
но все развивается по циклу — и скоро люди осознают и примут эту истину.
сcылки на крупные проекты уже давал —
wordpress.com, www.bluehost.com/wordpress-woocommerce
Шаблоны на голом пхп опасны, особенно если верстку на движок натягивает верстальщик с базовыми навыками js, вдруг прошедший курсі Попова.
О славянские боги! В чем проблема?
>Шаблоны на голом пхп опасны
Зато понятны всем!
Не берите на работу начинающих верстальщиков. Начинающие верстальщики эти ваши шаблонизаторы тем более не знают.
Разве в шаблонизаторах нельзя выполнить php код? В smarty легко. Даже без «тега» {php}
Это проблема?
Все разрулит построитель запросов.
>тысячами роутов
Шо вы курите?
>не на впс-ке за 5 баксов
У меня шаред хостинг держал 50К пользователей за 2 часа на самописи.
Новый рекорд уже на ВПС за 6 баксов:
115К пользователей в день, 240К хитов, 30К пользователей за час.
>на ферме в несколько сотен серверов
Какие фермы? Там никто не использует фреймворки (мейнстримовые).
>Все эти «ненужные» абстракци позволяют в итоге снизить сложность проекта.
Как по мне, только повышают.
Шо вы курите?
Сотня сущностей и для каждой хотя бы 4 операции — уже почти полтысячи.
Как по мне, только повышают.
Хорошие абстракции — понижают, лишая необходимости думать о реализации. В документации к абстракции есть всё, что нужно для её правильного использования. Кстати, абстракции — краеугольный камень минимум двух принципов из SOLID — они все пять не нравятся или только два?
Это Вы типа REST API собрались строить?
Это псевдопрограммирование.
>Хорошие абстракции — понижают
Хорошие — да.
На фреймворках — сплошные дырявые.
Мне нравился Делфи с его библиотекой.
Это Вы типа REST API собрались строить?
Это псевдопрограммирование.
Это как псевдо?! Для вас программирование это шаблончики на сервере рендерить?
На фреймворках — сплошные дырявые.
Допустим, Symfony HttpFoundation Request — где дыры?
Там нифига не написано, как они тюнили.
А большинство запросов там — по первичному ключу.
Это по ходу не сайт, а какой-то сервис по отдаче данных по первичным ключам. :)
30 ms — время генерации — много.
Конечно нужен строитель запросов.
+1 за роутинг на стороне вебсервера. Это его хлеб. Фреймворки проблему не там решают. Получаем оверхед.
Нету оверхеда.
Не нужно разбираться, как строить роутинги, минус одно звено в программировании, система проще.
Что имеется в виду под «о каждой функции»?
На работе на одном из проектов 10 бекэндов.
Но балансировщик — это не дело программистов.
Балансировщик шлет трафик не по разделам на разные бекэнды.
Обычно балансировщик работает на бекэнде с http-сервером.
А так можно обойтись без http сервера.
Балансировщик шлет трафик не по разделам на разные бекэнды.
Балансировщик (http) шлёт запросы как ему скажут. Скажем, запросы http://example.com/users он будет слать на один бэкенд, запросы http://example.com/posts распределять по десятку других бэкендов, а статику проксировать на CDN. И да, балансировщик, как и веб-сервер — это не дело программистов в общем случае. Но и дергать админов на каждый новый контроллер — очень быстро админы скажут, что это не их дело роутинг настраивать, будут требовать единую точку входа на приложение.
Сейчас работаю в проекте под большой нагрузкой, где делали изначально роутинг на веб-сервере. Вышел такой некислый кусок nginx строк на 800. Прошло несколько лет, наняли SEO-оптимизатора. Интересно, вы представляете, сколько грабель было собрано на продакшене, пока отрубали банальный trailing slash в ссылках?
2. Для перевода url на без / можно написать 1 правило.
3. У меня нет в конфиге нгинкса завязки на trailing slash. Если она у вас была, то она может быть и в роутинге на приложении.
2. Писали — наступили на грабли. Некоторые сразу увидели, некоторые спустя какое-то время
3. У нас весь роутинг в nginx, приложение получает только GET запрос.
Проблема тут не совсем в том, где роутинг изначально делался. Когда вы работаете один или в команде есть человек, который стоял у истоков и всё хорошо знает — замечательно. Но часто бывает, что проект живет больше 5 лет и люди менялись каждые полгода-год. В итоге приходит человек вроде меня и видит не то, что даже вавилонскую башню, а просто сборную солянку. И всё потому, что изначально был задан дурной тон в разработке, велосипедостроение, никакой оглядки на best practices и стандартизацию. Всё начинается с мелочей, а заканчивается «разбитыми окнами». Разобраться и навести порядок — не знаю реально ли. Уже не первый раз в такое попадаю. Раньше сваливал побыстрей.
и не предоставлют никаких конкретных инструментов для решения задач
Если вы имеете в виду бизнес-задачи, то в точку. Фреймворки — не инструменты для решения бизнес-задач, фреймворки — инструменты для создания инструментов решения бизнес-задач, обеспечивая типовые решения для типовых инфраструктурных задач. Лучше всего они себя проявляют, когда бизнес-задачи не типовые. Если ваша бизнес-задача — создание инструмента коммуникации с клиентами в виде стандартного блога, то писать блог на фреймворке не самое оптимальное решение в общем случае. Но если решили использовать готовое решение, то надо иметь в виду, что в случае если вам стандартного блога станет мало, то кастомизация готового решения в общем случае обойдётся дольше и(или) дороже чем если бы написали на фреймворке.
Правда, это скорее подойдет, если вы сами разбираетесь в программировании.
Никто ядро системы каждый раз с нуля не пишет.
Я бы и не был бы против фреймворков, если бы они были толковыми.
Но они упоротые и доставляют больше проблем, чем дают выгоды.
если б этот чудо фрймворк sympony показали на примере для чего то более серъезного — типа написания своего фейсбука. или гугола
я б дейсвительно задумался о его применении.
В общем-то, дальше уже не о чем говорить.
да вы не думайте, вам это вредно. продолжайте обмазываться своими самописями и всё у вас будет хорошо. главное намазывать толстым слоем.
WordPress самопись, лолчто?
~14 лет разработки и развития, сотни разработчиков ядра. c сохранением обратной совместмости,
а не переписыванием следующей мажорной версии с нуля как это любят делать во всех известных фреймворках.
Крупный коммерческий сервис wordpress.com с крупной коммерческой компанией https://en.wikipedia.org/wiki/Automattic
и многих других — есть кому вкладывать деньги в разработку и развитие, а значит это уверенность в будущем.
Вот просвещайтесь https://ru.wikipedia.org/wiki/WordPress
и еще вводная статья на хабре https://habrahabr.ru/post/282401/ для тех кто не в теме.
{{ render(controller('BloggerBlogBundle:Page:sidebar' ))}}
нужно бить по рукам.
можно просто заинклудить вьюху с сайдбаром и все.
а где делать выборки тегов и последних комментариев?
Спасибо за ответ. А форму добавления комментария тоже в таком случае лучше упаковать в отдельный "виджет" или это уже будет экономия на спичках?
Whenever you find that you need a variable or a piece of information that you don't have access to in a template, consider rendering a controller. Controllers are fast to execute and promote good code organization and reuse. Of course, like all controllers, they should ideally be «skinny», meaning that as much code as possible lives in reusable services.
Symfony Book
Ваше «слишком затратно» в цифрах как-то выражается?
Symfony Book в свою очередь содержит информацию которая призвана популяризировать фреймворк, показать что не все так сложно, поэтому не всегда в нем описывают сложные подходы.
Ради интереса я когда то делал замер, данных для вывода было немного(облако тегов). С кастомной функцией гораздо быстрее рендерится страница.
Но чисто сементически мне это тоже не нравится.
данные собирать сервисом, рендерить — вьюшкой, обернуть все это в некий компонент, не завязанный на реквест (в отличии от контроллера) — компонент слоя View (виджет yii, extension twig'а). Все-таки контроллер традиционно это что-то работающее с реквестом юзера.
Я понимаю HMVC как слоеную архитектуру с адаптерами в виде контроллеров между слоями. В php-фреймворках традиционно один контроллер, поэтому именно семантически это выглядит некорректно. То есть вынеси экшн, назови виджетом — и все довольны.
render(component(...)) это и есть вызов контроллера для получения некого ресурса. Да, у этого ресурса нет внешнего урла (а может и есть, никто не запрещает). Но он точно так же может работать с реквестом, с контейнером, генерить какие-то данные и выдаёт какой-то респонс. И это именно то, что требуется в сайдбаре. Получить ресурс "данные для сайдбара" — задача более подходящая для контроллера, нежели для твиг-функции (которая вобще-то не должна делать ничего, кроме обработки и подготовки к выводу уже поступивших данных, а тут она в БД полезет, начнёт с моделью работать).
вызвать render('SidebarWidget'), который является инстансом некоего WidgetRenderer'а, семантически корректнее и srp'шнее, чем рендерить контроллер (хотя обе сущности могут функционально быть очень похожи).
Все мое имхо.
В симфони2 нет компонентов. Есть только контроллеры, которые получают реквест и выдают респонс. Компонент делает ровно то же самое — на входе название компонента (урл), на выходе респонс (html), тогда вопрос: чем компонент отличается от контроллера, и коль уже есть контроллер, то зачем нужен некий компонент? В симфони1 существование компонентов было оправдано тем, что они типа более легковесные, там не проверяются права и т.п. В симфони2, видимо, посчитали этот аргумент слишком незначительным, ну или были какие-то другие причины, я не знаю. При таком решении компонент-контроллер становится более независимым, а значит, более реюзабельным и тестируемым.
— контроллер получает данные (реквест), отдает json
— сериалайзер получает данные, отдает json
Является ли это описанием одинаковой сущности? Не отличаются ли они семантически, хоть и одинаковы функционально?
Контроллер рендерит всю страницу с помощью вьюшки. Виджет (отдельно формирующаяся часть вьюшки) рендерит часть вьюшки из вьюшки.
Экшн контроллера имеет урл, виджет не имеет.
Опять же протечка слоев — слой вьюшки запрашивает сущность из слоя контроллеров, хотя должно быть наоборот.
А если вам понадобится контроллер, который может быть доступен по урлу и может быть вставлен в виде "виджета", вы что будете делать? Ну например, форма логина, которая может быть в модальном окне и в body страницы, в зависимости от ситуации. Тут-то ваша "компонентная" логика и поломается.
Контроллер не обязан рендерить всю страницу, не пойму откуда этот стереотип. Он рендерит только то, за что отвечает (чаще всего — действительно за всю страницу целиком, но это не догма). И смысл разбиения страницы на несколько контроллеров — это делегирование ответственности.
Опять же протечка слоев — слой вьюшки запрашивает сущность из слоя контроллеров, хотя должно быть наоборот.
Вот именно. Вью говорит — у меня тут должен быть сайдбар, я хз что там за данные, нужны ли обращения к БД или не нужны, но вот ОН (контроллер) точно знает. Поэтому я сюда вставлю то, что ОН мне респонсит.
вы просто не смОтрите абстрактно на проблему. Если в симфони работает рендер контроллера из вьюшки, то это не значит, что оно верно. Я исхожу из того, что контроллер не должен таким образом рендерится, т.к. это не задача контроллера. Раз это не задача контроллера, значит, должен быть компонент, позволяющий это делать. Пусть это будет WidgetRenderer например. Ну SRP же.
>> А если вам понадобится контроллер, который может быть доступен по урлу и может быть вставлен в виде «виджета», вы что будете делать? Ну например, форма логина, которая может быть в модальном окне и в body страницы, в зависимости от ситуации. Тут-то ваша «компонентная» логика и поломается.
это другой кейс. Суть виджета: в провайдере данных и вьюшке, отображающей эти данные. Как я понимаю, new HtmlResponse((new SidebarWidget)->render()); без проблем отработает в симфони.
>> Контроллер не обязан рендерить всю страницу, не пойму откуда этот стереотип
>> Вот именно. Вью говорит — у меня тут должен быть сайдбар, я хз что там за данные, нужны ли обращения к БД или не нужны, но вот ОН (контроллер) точно знает.
Все остальное это как раз ваш стереотип, основанный на реализации виджетов в симфони.
То есть вы считаете, что в скобочках у «ОН» должно быть слово «контроллер», потому что привыкли так в симфони, а я считаю (вслед за классическим пониманием MVC из вики), что контроллер принимает данные от пользователя, и на основе бизнес-правил формирует вьюшку, а значит формирует ВЕСЬ выхлоп, а не часть. И дальше вьюшка ни с чем не общается — все свои проблемы в виде повторяющихся частей решает сама, в рамках своего слоя. Поэтому в скобочках у «ОН» должно быть все, что угодно, но только не контроллер.
Да поймите же, что в симфони2 нет разницы между компонентом и контроллером. И незачем её искусственно создавать. Во всех случаях, когда нужно проконтролировать генерацию вью, используются контроллеры. Частично или полностью, с урлом или без — это вы всё решаете каждый раз в частном порядке. Да, может быть в других системах штуки для генерации вью под названием "layout" называют "контроллерами", а штуки под названием "sidebar" называют компонентами. В симфони2 пошли другим путём. Контроллер контролирует генерацию вью. Если какому-то вью требуется для своего рендера другой вью, который контролируется кем-то, то он обращается к тому, кем оно контролируется, т.е. к контроллеру.
еще раз: компонент — это часть некоей системы. Это не понятие из мира Симфони. Компонентом может быть сервис, контроллер, виджет, рендерер, репозиторий, валидатор и так далее. Как видите видов компонентов много, а отличаются они — своей ответственностью.
$postService->findById($id) — возвращает Post
$postRepository->findById($id) — возвращает Post
Функционал и сигнатура одинаковые, а семантика и ответственность этих двух компонентов разная.
Должен быть компонент, рендерящий вьюшку на основе клиентского реквеста. Должен быть компонент, рендерящий часть вьюшки для реюзабельности. Две ответственности — два компонента.
Обоснование тем, что в симфони так, нерабочее, поскольку эта ветка началась именно с некорректности использования контроллера в качестве виджета.
$postService->findById($id) — возвращает Post
$postRepository->findById($id) — возвращает Post
Вот смотою и туплю, а зачем нужен $postService? Есть же репозиторий для этих целей.
Должен быть компонент, рендерящий вьюшку на основе клиентского реквеста. Должен быть компонент, рендерящий часть вьюшки для реюзабельности. Две ответственности — два компонента.
Оба на входе принимают аргументы, а на выходе — респонс для вью, и в этом заключается их ответственность, которая одинаковая в обоих случаях. Симфони не стал делить контроллеры на внутренние/внешние, вложенные/невложенные, с реквестом/без него. Контроллер должен выдать респонс. Если тебе нужен респонс, то обращайся к контроллеру. Всё остальное — повышение уровня абстрации.
ни в чем. Контроллер — один из видов компонентов, принимающий клиентский реквест.
>> Реквест — это всего лишь аргумент контроллера (он там может быть, а может и не быть).
аргумент метода — это реализация на уровне языка. Реквест — это данные, присланные клиентом.
Я выше давал пример:
— контроллер получает данные (реквест), отдает json
— сериалайзер получает данные, отдает json
реализация одинаковая — смысл разный. Поэтому две разные сущности. Повторю десятый раз: SRP, семантика.
>> Вот смотою и туплю, а зачем нужен $postService? Есть же репозиторий для этих целей.
разные слои. репозиторий — слой хранилища и отдаст мне запись, если она есть. сервис проверит мои права на получение данных например, и если права есть, получит запись из репозитория.
Аналогично контроллер возвращает html, хотя на самом деле html возвращает HtmlResponse внутри контроллера.
>> Контроллер должен выдать респонс. Если тебе нужен респонс, то обращайся к контроллеру.
респонс может выдать все что угодно. Опять же сужаете. Если существует что-то, что выдает респонс, это не значит, что респонс не может выдать что-то другое. У контроллера нет прерогативы на использование респонса.
>> Оба на входе принимают аргументы
аргументы метода — это синтаксис языка. У любого метода могут быть аргументы, и это не может быть доказательством чего-либо из обсуждаемой нами плоскости.
А вот смысл этих аргументов может повлиять на многое (см. пример контроллер/сериалайзер).
Вообще мы все это обсуждаем в контексте SRP или в контексте «так уже работает — сойдет»? Из второго принципа я уже вырос — стал плюсы solid чувствовать кожей, а нюансы семантики вижу невооруженным взглядом.
Кажется, я понял в чем ваше затруднение. Вы зачем-то наделяете вещи (контроллеры, сервисы) знаниями о том, кто, откуда и зачем их вызывает. Они не должны этого знать. Контроллеру должно быть всё равно, откуда он вызывается. Ему дают аргументы (реквест, объект, что угодно) и он на основании этих аргументов строит респонс. Его не должно волновать, вызывается он функцией из вью, из kernel или ещё откуда-то.
Конечно, сервис $postService имеет право на жизнь, но не проще ли воспользоваться уже готовым кубиком voters? Соединяем repository+voter+controller и получаем ваш postService. SOLID говорите? Ну-ну. И достать, и права проверить...
И я понял как вы решаете эту проблему. Вы просто делаете более высокоуровневую надстройку над фреймворком, чтобы вам было удобнее. Увеличиваете размер кубиков. Что ж, такая стратегия имеет право на жизнь, но тогда почему симфони? Почему не Yii или не битрикс с вордпрессом? Там это уже в готовом виде.
правильно я понимаю, что если у меня есть PostSerializer, но нет PostController, то я должен реквест закинуть в PostSerializer, ведь результат будет одинаков? Кто первый тот и отдает json?
Одно и то же повторяю разными словами по кругу.
>> Конечно, сервис $postService имеет право на жизнь, но не проще ли воспользоваться уже готовым кубиком voters?
абстрагируйтесь от симфони. Я не ищу решения какой-то проблемы в своем проекте на симфони — я с вами о программировании с т.з. правильности решений.
>> SOLID говорите? Ну-ну. И достать, и права проверить…
а в чем у вас проблема с этим? вообще понятие сервисов (не сервисов симфони) сервисного слоя вам знакомо?
>> И я понял как вы решаете эту проблему. Вы просто делаете более высокоуровневую надстройку над фреймворком, чтобы вам было удобнее. Увеличиваете размер кубиков. Что ж, такая стратегия имеет право на жизнь, но тогда почему симфони? Почему не Yii или не битрикс с вордпрессом? Там это уже в готовом виде.
вот это поворот. В каком месте я надстройку то сделал? я наоборот ухожу в сторону низкоуровневости, гибкости и развязаности, создавая сущность со своей ответственностью, вместо использования контроллера, где ни попадя, лишь потому что он может вернуть html.
Мы явно говорим на разных языках. Я не хочу переходить на личности, но посоветовал бы почитать книг вообще по архитектуре приложений, какие-нибудь энтерпрайз шаблоны Фаулера, ДДД Эванса. В вас чувствуется «специалист одного фреймворка», обосновывающий все конкретной реализацией, а не логичностью.
правильно я понимаю, что если у меня есть PostSerializer, но нет PostController, то я должен реквест закинуть в PostSerializer, ведь результат будет одинаков? Кто первый тот и отдает json?
Одно и то же повторяю разными словами по кругу.
Если у вас по какой-то неведомой причине PostSerializer возвращает объект Response, то да. Но очевидно что это не так, поэтому реквест надо закидывать в PostController.
а в чем у вас проблема с этим? вообще понятие сервисов (не сервисов симфони) сервисного слоя вам знакомо?
У меня как раз с этим никаких проблем нет :)) Есть механизмы, отвечающие за извлечение записей из БД, есть механизмы, отвечающие за проверку прав. Вы повысили уровень абстрации, объединив их в один механизм, который назвали postService.
Мы явно говорим на разных языках. Я не хочу переходить на личности, но посоветовал бы почитать книг вообще по архитектуре приложений, какие-нибудь энтерпрайз шаблоны Фаулера, ДДД Эванса. В вас чувствуется «специалист одного фреймворка», обосновывающий все конкретной реализацией, а не логичностью.
Что ж, на этом и предлагаю закончить эту увлекательную дискуссию. Благодарю.
в вашем программировании так не делают? Ваш контроллер случайно не извлекает ли из БД данные и не рендерит ли вьюшку?
Вы ведь знаете про толстые контроллеры?
>> Если у вас по какой-то неведомой причине PostSerializer возвращает объект Response, то да. Но очевидно что это не так, поэтому реквест надо закидывать в PostController.
контроллер должен вернуть строку, выводимую в браузер, консоль, выхлоп http-клиента. Остальное — вопрос реализации. Но собственно ответа вашего это не меняет. Теперь ваш сайт стал первым сайтом, у которого вместо контроллера сериалайзер.
Ок. Тогда закругляемся.
Ваш контроллер случайно не извлекает ли из БД данные и не рендерит ли вьюшку?
Именно контроллер должен привести модель в состояние готовности к обработке запроса от view. Именно контроллер создаёт представление и связывает его с моделью. Это основная ответственность контроллера — определить какой-метод какого объекта модели дернуть (при необходимости его создав или восстановив из хранилища), дернуть этот метод, определить какому представлению (при необходимости его создав) сообщить о результате (при необходимости его создав) и собственно сообщить.
Кстати, вот подумал, если вам очень хочется иметь компоненты (мне тоже хотелось, когда я слезал со своего велосипедного фреймворка на симфони), то их можно реализовать с помощью всё тех же мастер-реквестов. Ну и психологическую обёртку над render(controller(...)), например, render_component('sidebar')
:)
Контроллер генерит респонс. Он занимается только этим. В чём вопрос?
Контроллер возвращает не JSON. Контроллер возвращает Response (JsonRespose, извините что я опять про симфони).
https://github.com/symfony/http-foundation/blob/master/Response.php#L236
опять вы реализацию поставили выше сути. Что бы ни возвращал мой контроллер (в любой фреймворке), итогом будет строка, во чтобы она ни была обернута для целей инкапсуляции — хотя для вас это «кубик» и повышение абстракции, ведь можно просто в контроллере вывести все напрямую.
И да, в симфони также нет такого понятии как "страница", "вложенная структура" и т.п. Есть контроллеры, есть роуты, есть шаблоны. Все эти дополнительные абстракции, которые делают фреймворк более высокоуровневым, присущи другим продуктам, типа Yii. Вероятно, они даже в некоторых местах делают разработку удобнее. Но всё же, если нужен блог, то решения лучше вордпресса не найти. Симфони2 удивительный фреймворк. Он задаёт стандарты, предоставляя при этом чрезвычайно маленькие и несвязанные кубики. В Yii-подобных этого даже близко нет и не предвидится. Монолит, чрезвыйчайно кастомизируемый и чуть более современно написанный битрикс.
Измеряли, само собой, в prod? Каким образом? "Гораздо быстрее" — это насколько в процентах?
Кстати, говорят, на голом пхп ещё быстрее страницы рендерятся. Но фреймворк не только и не столько для скорости исполнения кода придуман. Если есть какая-то отделяемая многократно используемая часть шаблона, то для этого можно и нужно использовать render(controller(...)). А не наделять вью (да-да, кастомная функция твига это вью) несвойственными ей полномочиями.
Ну вы же понимаете, что это не показательно… Быстрее в 4 раза? Дело однозначно не в контроллере/твиг-функции, там просто неоткуда взяться такой разнице. Скорее всего вас с контроллерами что-то не то. Если у вас висят обработчики на события реквеста, проверьте, нужны ли они на ВСЕ реквесты, или же стоит ограничиться мастер-реквестами. Почти уверен, что дело в этом.
Так в чем я не прав?
>Документация во всех фреймворках показалась какой-то попсовой, вроде расчитаной на дебилов (http://blog.kpitv.net/article/frameworks-1/ )
Очевидно, с такой позицией начнётся драка. У меня есть желание бить по рукам тем, кто запрещает такое по неведомым причинам.
Озвученная причина несостоятельна. А вот с lazy load прикол (проблема) в том, что при больших количествах зависимостей между выбираемыми сущностями иногда бывает быстрее (даже в продакшене) использовать единичные доп.запросы. Потому что гидрация данных начинает сжирать какое-то невероятное время. И бывает быстрее выбрать только блоги+пользователей, а потом маленькими быстрыми запросами дополнить их телефонами+оценками+Х+Y+Z, чем выбрать сразу всё одним запросом…
Подрались и без меня.
А об этом я писал в своей статье:
«Сам подход, что запускается 1 контроллер глуп.»
«Нету возможности выполнить другой контроллер.»
Фреймворки явно с подходом «только один контроллер» для хоумпаджей.
В моей самописи «контроллеры» легкие. :)
Тоже сначала так думал, но потом понадобилось сделать так:
{{ render_esi(controller('BloggerBlogBundle:Page:sidebar' )) }}
Создание блога на Symfony 2.8 lts [ Часть 5]