Comments 55
Symfony, например, а потом полные аналоги на всех остальных фреймворках — а потом проверьте что быстрее будет. Останется ли CodeIgniter вообще в этом списке — тот еще вопрос.
Убедили, бросаю Laravel и перехожу на CodeIgniter.
Вот если бы на каждом из фреймворков был реализован какой то тяжелый механизм, и на нем протестировано, то было бы намного лучше.
Берем фреймфорк, реализуем структуру DDD/CQRS/CommanBus, вешаем RESTful API, создаем сущности с 10 мил. записей. Каждая запись имеет связь с пятью сущностями (каждая сущность еще 5кк записей), имеет периоды дат.
Делаем выборку по периоду х — y с связими и т.д.
В итоге получаем полезную информацию:
1) Скорость разработки
2) Костыльность
3) Скорость выборки
4) Скорость обработки
5) Возможности фреймворка
…
По такой методике фреймворк будут выбирать лишь олени.
Сейчас, небось, скажет, что и минусуют его тоже «олени».
Сейчас, небось, скажет, что и минусуют его тоже «олени».
А кто же минусует тогда? :)
Вы хотите сказать, что по хабровчанской статье можно выбирать фреймворк? :)
А какие в той статье нарушения логики?
Можете откомментить, статья постоянно улучшается.
Если сейчас ад, то ранее был ад в квадрате. :) Статья все же улучшилась.
Вы хотите сказать, что по хабровчанской статье можно выбирать фреймворк? :)
Их нужно выбирать не по статьям с просто берешь что лучше знаешь и где проще найти разработчиков/проекты. Далее в дело еще география подключается. Если мы говорим про европу — Symfony. Штаты — Laravel. Параметров для выбора много, но идея в том что в целом с большего все они (если брать популярные) похожи настолько что переход с одного на другой просто не заметите.
А какие в той статье нарушения логики?
причинно-следственные связи, манипуляция фактами и банальное незнание. Ну либо это просто жирный троллинг, либо не компетентность. Взять хотя бы фразу:
Фреймворки рассчитаны на запуск одного контроллера на страницу
Какието да, а какие-то нет. Возьмите symfony, там вы можете скомпоновать страницу из отдельных блоков, у каждого из которого будет свой контроллер (ну и общий контроллер для страницы). Выйдет вполне себе граф компонентов.
Или вот еще рядышком:
Необходимость в коде контроллера вызывать рендеринг вида явно
явное всегда лучше неявного. Однако популярные фреймворки (например symfony) предоставляют из коробки декораторы над контроллерами которые сами экспоузнут результат работы контроллера в шаблон (аннотация @Template
). Ну и никто не мешает вам это сделать самому на любом другом фреймворке.
Или вот еще золото:
Давайте тогда вернем register_globals.
в контексте рендринга шаблонов звучит это мягко скажем дико.
Чтобы обратиться к GET/POST/COOKIE/SERVER нужно использовать непойми зачем неудобные обертки
то есть мы против register_globals но при этом любим суперглобальные переменные. Вы видимо все же не потому против register_globals
ибо глобальный стэйт пораждает связанность кода, а просто так. Ибо просто глобальный стэйт вам ок.
Параметров для выбора много, но они (если брать популярные) похожи настолько, что переход с одного на другой просто не заметите.
Да потому что и фреймворк-то и не нужен. :)
Ведь где происходит основная возня с кодом?
В обработке данных проекта и их выводе.
Этой возней можно заниматься хоть на CMS, хоть на самописи. :)
Какие параметры еще есть, кроме популярности в регионе? :)
Возьмите symfony, там вы можете скомпоновать страницу из отдельных блоков, у каждого из которого будет свой контроллер (ну и общий контроллер для страницы). Выйдет вполне себе граф компонентов.
О, норм я не знал. :) Я же не буду проверять все фреймворки. В документации этот вопрос не освещался вроде ранее.
Ну, это то чего мне не хватало.
А до Вас за 2 года никто об этом не сказал.
(Сказали только, что можно ~полукостыльно, но это нежелательно якобы из-за дикого оверхеда).
Может это появилось недавно, после прочтения моей статьи? :)
явное всегда лучше неявного.
У меня тоже явно. В параметрах вызова «контроллера» указывается, какой шаблон выводить.
Просто код вызова шаблона программисту обычно не нужно вызывать.
Однако популярные фреймворки (например symfony) предоставляют из коробки декораторы над контроллерами которые сами экспоузнут результат работы контроллера в шаблон (аннотация Template).
То есть имеем одноразовые контроллеры, которые умеют рендерить только 1 шаблон?
А как же все рассказы об MVC? :)
Давайте тогда вернем register_globals.в контексте рендринга шаблонов звучит это мягко скажем дико.
extract() делает примерно то же, что и register_globals :)
Вместо работы с массивов подсовывает переменные с именем, взятым из ключей массива.
то есть мы против register_globals но при этом любим суперглобальные переменные
А одно мешает другому? :)
Ибо просто глобальный стэйт вам ок.
А не всегда глобальное состояние это плохо.
Можно же обратиться к «состоянию» приложения?
В том же Yii 1.1 параметры так работают.
Ну и какой смысл не использовать GPCS, если под оберткой все равно работа с GPCS? :)
Я не говорю, что всегда лучше работать напрямую с GPCS. Иногда можно использовать свою обертку.
П.С.
А документация и продвижение фреймворков разве не расчитано на дебилов? :)
П.П.С.
Всем ораторам.
Читайте внимательно. Я никому не запрещаю пользоваться фреймворками!
Я лишь привожу свой опыт, что можно обойтись и без них.
П.П.П.С.
Кстати, статья дополнилась 2 пунктами недостатков в самом начале.
Суть примерно такая: Not invented here. :)
«У меня виджеты и контроллеры — одна сущность. Примерно как компоненты в Битриксе. Любой компонент может вызвать другой компонент.»
Что вам мешает так же работать? Просто отстаньте от контроллеров, контроллер контролирует страницу, логику из него следует убрать и сделать из него простой включатель/выключатель
Или в модель передавать параметром суперглобал $_POST? :)
Сначала вообще не понятно с чего такие вопросы. как они относятся к предыдущему комментарию. Но потом становится понятно, что они из-за восприятия вами этого комментария через призму вашей некомпетентности.
Я попытался понять, что вы имеете в виду, и наверно даже понял.
Задача контроллера применительно к web это обработка связи запрос-ответ (включая заголовки).
Поэтому у вас в контроллере должны каким-то образом быть понятия request и response.
Но если вам пофиг на ООП, вместо request можно работать напрямую с $_GET и $_POST.
Надо выбирать из этих $_GET и $_POST нужные данные и передавать их в модель/сервис/что-то-еще, что реализует бизнес-логику.
Работать с $_POST в модели не надо.
Передавать параметром $_POST в модель не надо.
Бизнес-логику в контроллерах писать не надо.
Но если вам пофиг на ООП, вместо request можно работать напрямую с $_GET и $_POST.
Это все детали.
Надо выбирать из этих $_GET и $_POST нужные данные и передавать их в модель/сервис/что-то-еще, что реализует бизнес-логику.
Бизнес-логику в контроллерах писать не надо.
Ну вот.
А это будет как бы и не бизнес логика.
Это как раз будет построение параметров для «модели».
А так как от модели никакая другая логика кроме выполнить запрос и отдать данные не требуются, то можно из контроллера вызвать нужный метод сущности и все. :)
П.С.
Статья чуток изменена касательно буквы М.
Код, касающийся модели можно размещать в контроллере, если он простой и нету дублирования.
Это как раз будет построение параметров для «модели».
это больше похоже на паттерн адаптер, когда вы один интерфейс (http) приводите к другому (интерфейс приложения). Дабы приложение ничего не знало о http.
А так как от модели никакая другая логика кроме выполнить запрос и отдать данные не требуются
Вся проблема в слове "модель". Вот вам чуть-чуть более детализированное представление о том что такое MVC. Для начала посмотрим на вариант того что БЫЛО раньше, во времена десктопов, когда у нас UI layer имеет свой жизненный цикл. Если упрощенно, возьмем виджет для отображения вашего баланса. На этом виджете так же есть кнопка "вывести деньги". По клику происходит ивент "onClick" и его обрабатывает контроллер. Контроллер просит модельку представляющую баланс провести операцию. То есть тут задача контроллера лишь сконвертировать асинхронное действие пользователя в синхронный вызов метода модели.
Но дальше интереснее, потому что модель в этой схеме все еще относится к UI. Ее задача — отделить представление от приложения. Это эдакая точка входа, вершина графа объектов. Она же просит другой объект совершить операцию (делигирование ответственности), и когда та закончит спросит у еще одного объекта "а какой теперь у меня баланс?". Если баланс поменялся — кидаем событие, которое ловит вьюшка. По этому событию вьюшка обновляет циферку баланса.
Собственно а теперь размышляем что у нас в WEB. Если мы будем рассматривать только бэкэнд, то у нас UI для приложения это http запросы и ответы. У нас нету "вьюшки" как таковой, точнее под вьюшкой мы разве что http можем понимать, эдакая пассивная вьюшка. "Контроллер" теперь выполняет роль конвертера http запросов в запросы к приложению. Причем на нашу операцию — вывод денег, мы отдадим не баланс а редирект на то место где можно этот баланс глянуть. application layer ничуть не поменялся, а вот ui layer теперь представлен только контроллерами.
то можно из контроллера вызвать нужный метод сущности и все. :)
в моем примере мы именно так и делаем для просмотра баланса. Поскольку тут все хорошо, мы просим какой-то объект (не хочу использовать термин сущность потому что может быть конфликт с другими терминами) предоставить нам информацию по балансу для определенного юзера. И все, далее мы заворачиваем это в http ответ и вуаля. Все четко и красиво.
Но вот в случае с выводом денег нам все равно нужен объект который инкапсулирует в себе всю операцию. И этот объект не должен ничего знать о HTTP.
То есть правило простое. Контроллеру на одно действие нужен один объект от приложения, который предоставит всю необходимую информацию для ответа за один вызов одного метода. Далее мы в контроллере уже будем заниматься формированием нужного нам представления, рендрить из этих данных html или json сериализовать, не важно.
Если такого объекта не находится, есть только один вариант: сделать такой объект. Этим объектом иногда могут служить другие контроллеры (например мы рендрим страницу и нам нужна информация для нескольких блоков, HMVC и все такое).
Что бы быть конкретнее по поводу "одного объекта и одного вызова метода этого объекта на действие контроллера", еще рассмотрим batch обработку. Когда нам может придти массив действий. Но хоть контроллер (и экшен контроллера если хотите) у нас один, действий много. А потому в этом случае просто на каждое действие ровно один вызов метода приложения.
tl;dr все на самом деле сводится лишь к тому что бы у нас направление зависимостей были в нужную сторону, от менее стабильного (то что чаще меняется) к более стабильному (то что меняется реже).
Просто иногда (часто) надобности в модели нет.
Сначала удобно набросать в контроллере. А потом по мере развития можно и вынести это в модель, когда будет понимание, что там должно быть.
Просто иногда (часто) надобности в модели нет.
вы ничего не поняли из того что я написал, да?
Сначала удобно набросать в контроллере. А потом по мере развития можно и вынести это в модель, когда будет понимание, что там должно быть.
Это так. Но если вам такой подход удобен, сразу можно сделать следующие выводы:
- юнит тесты для слабаков,
- TDD/ATDD придумали трусы
- BDD никогда не надо
Вы стремитесь к 100%-ому покрытию?
ключевое слово — стемиться. 100% покрытие тестами невозможно (ну только если у вас все очень просто). Вопрос здравого смысла.
Что до вашей статьи...
Unit-тесты же можно не писать, так как они не выявляют интеграционные проблемы.
самый ужасный вывод который можно сделать...
Unit-тесты же можно не писать, так как они не выявляют интеграционные проблемы.самый ужасный вывод который можно сделать...
А-ха-ха.
А разве не так? :)
Рекомендую к просмотру. Лучшее видео на эту тему.
На бусурманском обычно льют воду ни о чем, говорят о тривиальных вещах, будто это какое-то открытие. :)
На выходных попробую. :)
П.С.
Постоянные читатели статьи.
Разве она со времени появления 2 года назад не улучшилась?
Особенного внимания заслуживает цитата:
Зачем извращаться и писать запрос на php, если можно просто взять и написать? Абы було?
Если возникает такой вопрос — то тут явно к психиатру, а не на хабр.
Господи, если ты пишешь проект сам — флаг тебе в руки, хоть там сферического коня в вакууме сочиняй
Господи, если вы пишете проект на фреймворке — флаг вам в руки, хоть там сфе…
Если возникает такой вопрос — то тут явно к психиатру, а не на хабр.
Ты тоже думаешь, что я пропагандирую писать запросы, как в комменте оратора ниже ( MetaDone )? :)
Может вам к психиатру? :)
Ищите комменты от «M-A-XG» в той теме. :)
лично по моим наблюдениям его круто применять в тех местах, где все можно реализовать только его средствами, например в апишках — тогда профит будет ощутимым
— Фронт, если это не js, а шаблонизатор на php, то это чистый phalcon с volt и моя библиотека CURL запросов. Делает он API запросы которые кеширует
— API на Phalcon имеет пару хелперов по работе с базой, ну и есть крупные библиотеки по работе с EXCEL ид но они запускаются только по необходимости опреленными скриптиами.
Так что все вроде справедливо
Логика на уровне "Инфляция всего 2%! Умножь на 1000 и грусти".
В вашем умножении нет смысла. Вот если бы у вас был класстер из 200 серваков, и разница по стоимости железа на 10% была бы соизмерима с окладом разработчика в месяц, тогда об этих 10ms можно уже заморачиваться. И то далеко не факт что это будет одним из первых пунктов в плане приоритетов.
Но тут важный момент — когда вам надо 200 серваков, вы уже состоявшийся продукт. И тут уже есть возможность потратить недельку на то что бы "вот тот жирный компонент фреймворка заменить узкоспециализированным под нашу инфраструктуру".
И преимущество фреймворков типа symfony в том что они как раз таки позволяют это сделать относительно безболезненно. Надо заменить роутер на что-то побыстрее в контексте наших задач — вуаля. Надо ускорить запросы на чтение — ставим мидлварю которая будет ранать наш http kernel в cli режиме без необходимости бутстрапить приложение полностью.
С другой стороны на старте продукта у вас есть сэт универсальных компонентов, ведь мы в начале редко знаем как оно что меняться будет. Потому чем больше мы умеем тем лучше для бизнеса. А если архитектура достаточн модульная "узкие места" когда они станут узкими можно уже будет подправить.
Тут аналогия с ORM. Можно юзать их, полагаться на лэйзи подгрузку данных, а когда спустя месяц-два запросы стабилизируются — оптимизировать с использованием явных джойнов и минуя дорогой этап гидрации. А быть может у нас из 200 серваков 20 это реплики базы данных, что бы запросы не вешали систему, и тогда 180 серваков с PHP уже явно не будут самым значительной статьей расходов как с экономической точки зрения так и с точки зрения производительности.
tl;dr идея в том что бы обменять производительность на гибкость и скорость разработки и при увеличении стабильности модуля уже загоняться по оптимизациям если в этом есть существенный профит с экономической точки зрения.
Как выбрать тот самый PHP-фреймворк. Сравнительное тестирование