Комментарии 118
Вся суть Symfony.
4 (четыре, ЧЕТЫРЕ) статьи, чтобы сделать один бложик. Поистине, фреймворк для мазохистов.
Давайте теперь все возьмемся за руки, прочтем несколько мантр про энтерпрайз, бандлы и аннотации и дружно пройдем сертификацию у св. Фабьена.
Не вижу проблемы в том, что автор с излишней подробностью расписал для новичков на 4 статьи. При этом затрагивая далеко не только фреймворк.
Говорят, фреймворки ускоряют разработку.
Но с таким фреймворком, как Симфони приходится долго мудохатся даже с простым блогом.

Вот трезвый взгляд на фрейморки:
http://blog.kpitv.net/article/frameworks-1/ (статья обновлена)

Местная публика явно враждебно настроена против альтернативной точки зрения.

я тут хотел опять написать что вы не компетентны говорить об "алтернативных" точках зрения, но потом подумал… а какая разница. Вы только больше расшатываете разницу между разработчиками на рынке труда и мне в принципе это даже в каком-то смысле выгодно. Вопервых адекватные люди не купят этот булшит, а меня интересуют только они, а во вторых за счет больешго количества новичков которые "не любят фреймворки" адекватные люди будут более ценны на рынке труда.

Присоединяюсь к Вашему мнению. Очень здравая точка зрения.
Не знаю, к счастью или к сожалению, но фреймворки лишь маскируют это отличие. Как только автор вышел за пределы фреймворка и начал писать на php, так сразу вылезла substr, которая не дружит с юникодом. Да и truncate для твига есть в экстеншинах, не знаю включён ли он по дефолту в симфони. И я бы счёл это за ошибку в спешке, если бы не пример с php-шаблоном, где автор проигнорировал экранирование выводимых данных, что является смертным грехом и едва ли не главной фичей твига в сравнении с нативными шаблонами.
В Symfony еще с версии 2.3 в Twig по умолчанию включено автоматическое экранирование.
norgen, miraage так я и писал, что не хватает экранирование в примере с нативным шаблоном, и что substr использовать в эпоху юникода нельзя.
1. Если фреймворки так просты, то почему на них выше ЗП?
2. Фреймворки и так забиты разработчиками, которые без фреймворка не умеют думать.
3. Адекватные люди — это люди с баблом? Да, у них часто логика типа: вот отвалим дохрена бабла, получим качественный продукт.

Но часто получаем велосипеды на фреймворках.

В конторе, в которой я работал с самописной ЦМС, гребут бабло лопатой, так как хорошее портфолио.
И пофиг, что та ЦМС необновляемая, и пофиг, что с той ЦМС работает только эта студия, и пофиг, что SQL запросы на ней все написаны руками.
Главное навешать клиенту. :)

Кстати да, чем больше людей будет на фреймворках, тем более будут ценны настоящие специалисты.

Я писал и на фреймворках, и на CMS, и на самописи. :)
Потому что фреймворки позволяют писать быстро и качественно, при этом и поддержка обходится значительно дешевле.

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

Вот смотрите в статье есть отсылка емейла, без фреймворка
Справедливости ради, отправкой имейлов занимается не фреймворк, а библиотека.

письмо слалось не сразу, а сервером очередей и не вызывало дедлок под нагрузкой
Простите, а как отправка писем может вызывать дедлок?
Я использую внешнюю библиотеку для почты.

Я ж не против стороннего кода…

Я против глупостей фреймворков.
Я против глупостей фреймворков.

и с такой мотивацией мастерите свои велосипеды? Это как-то нелогично. Ладно бы использовали компоненты и на них строили все.

Что вы считаете глупостями фреймворков? В частности глупостью Symfony?
Ну так современный фреймворк вроде symfony это и есть набор библиотек. Так что вы занимаетесь самообманом.
>1. Если фреймворки так просты, то почему на них выше ЗП?

Может потому, что с фреймворками работают люди чуть умнее тех, кто всегда пишет с нуля? Или потому, что эти люди быстрее решают задачи?

>2. Фреймворки и так забиты разработчиками, которые без фреймворка не умеют думать.

Ну да… Назовите plz пару известных людей, которые ПРОТИВ фреймворков. Реально интересно…

>3. Адекватные люди — это люди с баблом? Да, у них часто логика типа: вот отвалим дохрена бабла, получим качественный продукт.

Нет. «Люди с баблом» — это «люди с баблом». Адекватность и наличие «бабла» никак не пересекаются.

>Кстати да, чем больше людей будет на фреймворках, тем более будут ценны настоящие специалисты.

Серьезно?! ))) Расскажите это людям из мира 1С или Java ;)

>Я писал и на фреймворках, и на CMS, и на самописи. :)

Не верю! (с) Станиславский. Покажите plz, что вы написали на популярном фреймворке. Судя по вашему посту — вы даже результирующий sql-запрос из AR получить не можете, не то чтобы что-то написать))))
Может потому, что с фреймворками работают люди чуть умнее тех, кто всегда пишет с нуля? Или потому, что эти люди быстрее решают задачи?

Это насамом деле очень интересная штука. Допустим разработчик который хорошо знает фреймворк напишет продукт в 3 раза быстрее и за в 2 раза большие деньги, в итоге все в профите. И бизнесу это выгоднее, и продукт раньше выйдет, и разработчик получил больше.

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

Единственный вариант, по-моему, когда написанный с нуля продукт стоит дешевле — очень низкие требования к качеству кода, включая требования по безопасности, допускающие привлечение очень низкоквалифицированных разработчиков, пользующихся некомпетентностью заказчика в вопросах разработки, когда он может сформулировать, что должно быть в продукте, но не может сформулировать чего быть не должно, а во фреймворках большинство «не должно» из коробки.
1. Самопись не значит, что каждый раз все пишут с нуля…
2. У меня нету роутинга, маппинга. Проще код — все довольны.
3. От атак фреймворк не защищает.
4. Во фреймворках нету функционала в коробке, это не ЦМС.
  1. Самопись значит что введение нового разработчика на проект займет больше времени и сопровождение проекта (устранение уязвимостей, банальный фикс багов) будет обходиться намного дороже.
  2. Это значит что у вас очень большая связанность системы.
  3. Он самых распространенных (CSRF, XSS, Sql injection) должен защищать или хотя бы предоставлять возможность минимизировать риски.
  4. Фреймворки реализуют стандартный функционал связанный с инфраструктурой. В этом их единственное назначение.
1. Не факт.
2. Это Ваша выдумка.
3. Никак не защищает. Возможно в шаблонизаторе есть htmlspecialchars по умолчанию.
  1. Факт. В 99.9% случаев самопись не оправдана ничем кроме как желанием разработчиков поразвлекаться. Это не означает что в ситуациях с фреймворками поддержка всегда будет дешевле — там можно тоже натворить дел, но в среднем стоимость и главное скорость разработки обычно выше, меньше рисков и т.д. У вас же может быть просто не репрезентативная выборка (я полагаю вы работали только с yii причем старым который сейчас смешно рассматривать как достойное решение).


  2. Простой вопрос. Как вы генерируете ссылки на другие маршруты?


  3. От CSRF защищает. От XSS защищает нормальный шаблонизатор (twig например). ОТ SQL иньекций защищает нормально настроенная база данных а так же prepared statements которые используют все адекватные люди.
2. В конфигах прописаны пути.

В Yii 1.1 пути хардкодятся :)
что значит «хардкодятся»? в yii1/2 как и в симфони и зенде, ларавеле и фалконе генерация урлов работает идентично — generateUrl($route, $params)
А не, работает. Сорри.

Это у нас аутсорсеры наговнокодили :)

Только контроллер не знает какие пути ему генерировать :)
Это у нас аутсорсеры наговнокодили :)

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

Самопись не значит, что каждый раз все пишут с нуля…

Если структуру приложения не пишут каждый раз с нуля, то значит просто используют самописный фреймворк
У меня нету роутинга

в корне сайта 100500 *.php файлов, ссылки на которые в шаблоне руками пишутся?
маппинга

Прямо в базу с браузера стучитесь? Клиент mysql на javascript?
От атак фреймворк не защищает.

От всех — нет. От распространенных типа csrf или sqlj — да, если не пытаться эту защиту отключать.
Во фреймворках нету функционала в коробке, это не ЦМС.

Во фреймворках есть функциональность в коробке, нет готовой функциональности по управлению контентом.

1. Потому что фреймворки — узкоспециализированная вещь. Найти толкового разработчика с опытом не так просто.
2. И что в этом плохого? Больше разработчиков, больший выбор для работодателя.
3. Люди с баблом разные бывают, как тражиры так и скряги.
1. Полностью кастомные решения куда более узкоспециализрованная вещь, чем решения на сколь-нибудь популярных фреймворках.
С кастомными решениями проблема в том что нужно не только найти специалиста, но и научить его. На это тратится больше времени и средств, чем если бы в продукте использовался популярный фреймворк.
Жаль автор не показал, своё «самое лучшее» творение, например на гитхабе.

тот самый код, который, по его словам, может понять каждый разработчик.

P.s. согласен с Fesor.

К слову да. M-A-XG, выложите на гитхаб как время найдется. Хоть спорить потом можно будет более предметно.

http://blog.kpitv.net/article/когда-будет-публичный-релиз-ядра-15373/
Это пока ноу-хау.

Так в том же и соль. Сразу указать на недостатки. Один человек не в состоянии продумывать такие вещи.


Я не хочу распространять код, если он будет труднообновляем.

От вас требуется лишь пример а не готовый релиз очередного фреймворка


Я бы еще хотел как-то заработать на этом коде

не беспокойтесь. Ваш код никому не нужен.


Перед выпуском в паблик стоило бы подчистить немного легаси код

так же не беспокойтесь


Нужно написать документацию.

и так сойдет


Я не знаю, как систему встретят, будут ли пользоваться

напишите в ридми что это только пример "ноу хау" и что бы не пользовались

А что вы там хотите увидеть если автор сам пишет
В коде на Битриксе ничего плохого не вижу.
?
Не к альтернативной, а к специальному разжиганию срача. Как я вижу это уже не первый аккаунт тут. Надо бы как-то банить за мультиводство.
А, знаете, я прочел статью. Могу сказать, что альтернативной версии там ноль (хотя честно я ожидал такой версии). Но есть очень мало знаний, подмены понятий и обоснования своей т.з. на примере легаси-фреймворка 2008 года.
Ну в вашем посте бреда не меньше, а то и больше… Особенно понравилось вот это:

>Отстутствие нужных фич, которые можно легко реализовать в самописи.

Т.е. написать фичу на фреймворке — это плохо, написать без фреймворка — это хорошо)
Отстутствие нужных фич, которые можно легко реализовать в самописи, но сложно на фреймворке из-за его ограничений.
Я так и не помню все.
Не записывал. :)

Нормальные выборки из БД.
Фреймворковские конструкторы запросов — УГ.

Ну и ещке, к примеру, мой старший товарищ на прошлой работе зачем-то часть шаблона контроллера вынес в виджет, ибо оно должно выводится выше вызова контроллера.
А в виджете при этом было типа такого:
echo SOME_HTML // быдлопарсер не пропускает;

Говорю, кто эту херню написал?
Он обидился, говорит, это не херня, просто Yii что-то там не позволяет :)
>Нормальные выборки из БД.

Абсолютно во всех фреймворках, с которыми я работал, можно использовать plain-sql. Даже если взять в пример не любимый вами yii 1, насколько я помню, можно сделать так: $list= Yii::app()->db->createCommand('select * from post')->queryAll();

Так, для информации, я сам не использую AR/ORM, но с удовольствием пользуюсь фреймворками.

>Он обидился, говорит, это не херня, просто Yii что-то там не позволяет :)

Ну т.е. отваришь ваш мудак, но фреймворки — это плохо)))).
>можно использовать plain-sql

1. И привет sql-инъекции. Толковые разработчик заискейпит параметры или использует плейсхолдеры, но часто замечаю, что программисты на фреймворках уверены, что фреймворк каким-то магическим способом защищает от инъекций и допускают ошибки. :)
2. Хотелось бы, чтобы sql-запросы писались не вручную, хотелось бы большей гибкости.
Вручную замахаешься писать ифы при построении сложного запроса, расставлять пробелы, запятые и т.д.
  1. почитайте что-ли что такое prepared statements.
  2. попробуйте doctrine dbal.
1. Ну так большинство разрабов не применяет подготовленные выражения.
2. Вскоре наши сайты переедут на Symfony, посмотрим. :)
  1. Нет, они просто об этом могут не знать. Но большинство сегодня использует как раз таки prepared statemens за слоями абстракций.
  2. Не путайте DBAL и ORM. Я боюсь что вы будете одним из большинства кто не правильно готовит доктрину.
$select = $query->newSelect();
$select->from($this->prefix . "meta")
            ->cols(["*"])
            ->where('idObject = :idObject')
            ->join(
                    'LEFT', 'meta_keys AS s', 'meta.meta_key = s.id'
                )
            ->bindValues(array('idObject' => $idObj));

мне кажется все ооочень понятно — что и откуда берем.
а для случаев сложнее никто не мешает сделать plain-sql и передать туда нужные параметры. Если учесть что в типичном приложении наверно 80% простых запросов — такие штуки увеличивают скорость работы и повышают читаемость.
Ну а наговнокодить можно в чем угодно, все ограничено только кривизной рук. В самописном движке шансы на получение неструктурированной нечитабельной хрени резко растут.
1. Такой конструктор запроса неудобен, как раз о нем в статье написано.
2. Есть потенциальная возможность инъекций.

>а для случаев сложнее никто не мешает сделать plain-sql и передать туда нужные параметры

Это примерно как жирные модели.
Я против такого. Это псевдопрограммирование.

Средний уровень говнокода на самописи скорее всего буде выше, так как выше свобода.
Но могут существовать конкретно взятые качественные самописи.
Фреймворк только маскирует говнокодерство разработчика.
1. Удобство — понятие субъективное, если не умеете пользоваться — что угодно будет неудобным
2. Используйте prepared statement, а не вручную склеивайте запрос как строки

Ваша «конкретно взятая качественная самопись» лежит здесь. Если бы вы предложили что-то вменяемое, то диалог имел бы смысл. Конкретно ваша ересь не ускорит разработку проекта, не сделает его более структурированным и легким для входа, поэтому ваше мнение по этому вопросу не следует воспринимать серьезно. Если только вы в таком копаетесь — то пишите что угодно, главное коммерческие проекты не делайте
Фреймворк только маскирует говнокодерство разработчика

Ваше незамаскировано, в чистом виде — ни структуры, ни стандартов, в контроллере сборщик запросов. Уж не с таким кодом говорить о правильности подходов и архитектуре.
1. Вы даже не способны заценить красоту игры. :) Мудохаетесь с такими неконструкторами и думаете, что это вершина технической мысли. :)
2. Я не о себе говорю, а вообще. Большинство разрабов об этом даже не знает.

Приводите ссылку не на коммент, а на сам код, чтобы больше людей могло заценить красоту игры.

Любому битриксоиду данный код понятен и он должен заценить.
Я на заказ пока и не пишу. Только для себя. А то жалко отдавать ядро за бесцень. :)

И это только кусок контроллера.

В контроллере не сборщик запросов, а АПИ запрос.
Но вы просто задурманены фреймворками и не способны оценить красоту игры.
Только прикрываетесь фреймворками, а сами продумать и реализовать архитектуру неспособны.
Вы даже не способны заценить красоту игры


вы даже не способы сформулировать четкий список минусов.
Я не о себе говорю, а вообще. Большинство разрабов об этом даже не знает.


Большинство не знают что используют prepared statements когда работают с query builder-ами. Они дают возможность сэтить параметры к запросам и люди просто этим пользуются. В этом собственно соль, для этого абстракции и вводятся. Что бы меньше думали о всяких там мелочах, о которых кто-то за нас уже подумал.
А то жалко отдавать ядро за бесцень. :)


Жалко, но придется. Вы впустую тратите свое время.
В контроллере не сборщик запросов, а АПИ запрос.


Задача контроллера — дернуть один метод приложения (или два, один на запись и один на чтение). Ну и соответственно подготовить данные на вход и результат для вывода. Все. Никаких запросов в базу оно делать не должно.
Но вы просто задурманены фреймворками и не способны оценить красоту игры.


Какой игры?
Только прикрываетесь фреймворками, а сами продумать и реализовать архитектуру неспособны.


Дайте определение термина "архитектура" в контексте программирования.
>Большинство не знают что используют prepared statements когда работают с query builder-ами.

Я об этом и говорю. Когда они попадают в чистое поле, то творят дыры, ибо сами думать не способны.

>Задача контроллера — дернуть один метод приложения

Это извращенное понимание MVC. А конкретно — жирные модели.
Жирность модели определяется предметной областью приложения (при правильном применении MVC). Есть приложения, где бизнес-логика заключается в тупом CRUD, то есть отсутствует по сути, а есть приложения, где очень сложная инфраструктура и большое множество сложных представлений составляют лишь малую часть от кода бизнес-логики.
Согласен.
Но в примере на говнокоде — тупой одноразовый CRUD.

тупой одноразовый часто становится не таким тупым. А сделать минимальное разделение ответственности не сильно усложняет код, даже наоборот.


p.s. для такого тупого CRUD-а есть кодогенераторы вообще.

Когда станет не тупым, тогда и будем думать.
Вы просто не понимайте красоты игры, поэтому вам кажется, что должно быть разделение.
В данном случае разделения быть не должно. :)
маньяк, режущий жертве лицо осколком стекла, тоже может думать, что украшает ее. странные в общем у вас представления о красоте

Просто жертва не понимает красоты игры.


p.s. Меня одного настараживают подобные фразы?)

мне тоже кажется странным, вспоминается «let's play a game» от пилы
>маньяк

Оу-оу-оу, палехче.
Тебя, Остап, не в ту степь занесло.
если это красиво — то боюсь представить как выглядит корявый код по вашим понятиям. когда излечитесь от синдрома, тогда и продолжим диалог
Такой конструктор запроса неудобен, как раз о нем в статье написано.


Чем он не удобен?
Есть потенциальная возможность инъекций.


Нет.
а мне надоело уже в каментах к каждой статье видеть эти ссылки на блоги и неадекватные доводы.
сказал а, говори б. покажи уже свое детище — не стыдись.
Мне тоже много чего надоело. :)
Я критикую фреймворки.
И я не обещал показать свое детище.
Бисер перед свиньями метать не собираюсь.
Может это ты неадекват?
Я критикую фреймворки.


вы с ними так много работали, я смотрю. Вы критикуете фреймворки на примере только одного, судя по всему с которым пришлось поработать. И вам уже объяснили что Yii это в принципе трэйдоф между качеством и скоростью разработки. Так вы еще и 1-ый Yii смотрите который уже давно устарел.
Хотите обсудить скрам, пишите у меня на сайте, а не сюда тащите… :)
в каждом твоем каменте, когда ты пытаешься что-то оспорить то приводишь пример свое детище. а у меня не так а у меня вот так.
я тоже могу сказать вы все говно — я один дантарьян. но мои слова все адекватные люди пропустят мимо ушей потому что нет как говорится пруфов. я читал что ты не хочешь открывать свое детище, хочешь на нем заработать и тд. но ведь ты можешь для подкрепления своих слов сделать гист конкретного куска кода и показать в качестве аргументов. что тебе мешает?

Я считаю что фреймворк это склад кирпичей. складывай дом сам.
Самопись это отливание кирпичей с нуля. дольше, на первый взгляд дешевле обходится кирпич, но в итоге будет дороже (поддержка, порог входа)

Я не против самописи, но если уже есть готовый компонент — почему бы его не использовать? не нравится пиши свой — трать время.
Мне как-то техдир запретил использовать pear библиотеки. Типа он напишет свое лучше и тд. в итоге куча дыр, багов, негатива и куча времени на их исправление, пока не взял инициативу в свои руки не начал использовать pear ( было еще до композера).

Половина недостатков фремворков по твоей версии — это неудобно, непонятно, сложно.
Все это субъективно.
Мне допустим все удобно, понятно, и дебажить не сложно — есть xdebug.
Некоторые пункты вообще смутили:
— Нету добавления хлебных крошек.
— У добавленных цсс/жс файлов нету признака, что файл изменился
— Нету нормальных готовых компонентов, например меню. Меню каждый обязан написать сам

На мой взгляд это вообще не должно обсужаться. Это больше относится к cms. cms != framework. Да их нет, и быть не должно. Напиши сам. Или посмотри мб кто нить уже написал похожее и выложил на гитхаб/композер.
А зачем примеры кода?
Вам же даже сам подход не нравится…

>Я не против самописи, но если уже есть готовый компонент — почему бы его не использовать?
Допустим я не против фреймворков. Но когда у меня все написано и все сайты на самописи, то смысл в них? :)
А также у них есть фатальные недостатки. :)
Если у вас нету своего ядра, то пользуйтесь фреймворками дальше. :)

>Половина недостатков фремворков по твоей версии — это неудобно, непонятно, сложно.
Просто есть куда стремиться…

>Некоторые пункты вообще смутили
Не знаю, почему смутили. О хлебных крошках и меню я говорю не о шаблонах, а скорее о едином интерфейсе у всех на одном фреймворке.
>А зачем примеры кода?
За тем, что Вы в каждом посте, затрагивающем фреймворки, диким ором орёте о том, что фреймворки гуано, а Вы такой замечательный и у Вас есть своё собственное МЕГАЯДРИЩЕ холеное и лелеяное с 2000какогото года, но Вы нам его не покажете, потому что мы все тут тупорылые снобы, не способные осознать всю красоту и элегантность Ваших решений. А те из присутствующих, кто проникнется Вашими идеями, обязательно бросят свой говёный %framework_name% и побегут пользоваться Вашим божественным продуктом, тем самым лишив Вас чудовищных прибылей.

Вы постоянно упоминаете какое-то свое ядро абстрактное в вакууме, но пока никто не видил пруфов о том, что оно действительно такое удобное, как Вы его описываете. Соотвественно все упоминания о том что «все фреймворки гавно, у меня свое удобное и правильное ядро» воспринимаются как «я не осилил yii, поэтому написал своё»

Иметь собственное мнение — это хорошо, но выпячивать его так, как это делаете Вы — абсолютно не обязательно. Тем более что, повторюсь, никто не видел Вашего ядра и о том как всё в нем правильно и замечательно мы можем судить только с Ваших слов.
Я ж спорю не с кодом фреймворков, а с самим подходом…
Зачем тут мой код? :)

А мое ядро не публикуется не только потому, что я боюсь потерят мегаприбыли.
Там и другие причины есть. А платным оно вряд ли будет. Будут другие способы монетизации.

>я не осилил yii, поэтому написал своё

Ядро было написано до того, как я сел за Yii.
В Украине очень популярный Yii, и на 3 работах доводилось работать именно с дремучим 1.1 :)
Он везде был приготовлен некачественно. Но мою критику Yii никто не воспринимал тоже.
>Я ж спорю не с кодом фреймворков, а с самим подходом…
Я так и сказал. Знаете выражение «характер как и член должен быть твердым, и характер так же как и член не стоит выпячивать»? Вот вы именно этим и занимаетесь, выпячиваете свою альтернативную точку зрения. Это было бы хоть сколько-нибудь обоснованным, если бы вы могли привести хотябы куски кода, чтобы не быть голословным, возможно вашу точку зрения и приняли бы как-то. Но вы свои слова о том, что фреймворки говно, а у вас все круто, подтверждаете только своими же словами. Вы не википедия, на слово вам никто не поверит.

>В Украине очень популярный Yii, и на 3 работах доводилось работать именно с дремучим 1.1
ок, не спорю, yii популярен, но то что вы работали с дремучей её версией — это еще не означает, что все фреймворки говно. Это даже не означает, что yii2 говно. Но вы же наверное даже и не пробовали заглянуть в yii2?

Вам не хватает каких-то хлебных крошек, меню и еще какой-то фигни которая не относится к фреймворку. Кто мешает вам написать средствами фреймворка компонент или модуль который реализует нужный вам функционал и тягать его по всем проектам на этом фреймворке? Когда мне чего-то не хватает в юи я просто открываю интересующий компонент юи, полчаса трачу на то, чтобы изучить его код и пишу нужный мне функционал с использованием кода фреймворка(или без использования если нужна универсальность). Дальше этот функционал упаковывается в композер пакет и я могу к любому проекту его прикрутить.

>Он везде был приготовлен некачественно.
Будьте уверенны наговнокодить можно на чем угодно. Ваша самопись не исключение. Человек не знакомый с деталями вашей реализации с тем же успехом наговнокодит и на вашем ядре. Тут вопрос опять же не к фреймворку, а к прямоте рук которые на этом фреймворке что-то готовят.

Опять же, мы почему-то допускаем, что ваше ядро если не идеально, то как минимум написано хорошо, но пруфов никаких и мы вынуждены верить вам на слово. На поверке то может оказаться велосипед на костылях? :)

Я собственно говоря к чему растекся мыслью по древу? Обосновывайте свою точку зрения какими-то более авторитетными источниками или примерами своих реализаций. В противном случае — все что вы делаете — просто захламляете темы неподтвержденным мракобесием.
Смысл в кусках кода, если всех устраивает подход фреймворков?
Я не говорю, что у меня все круто.
У меня нет описанных недостатков.

>это еще не означает, что все фреймворки говно

Во всех фреймворках похожие подходы…

>Кто мешает вам написать средствами фреймворка компонент или модуль который реализует нужный вам функционал и тягать его по всем проектам на этом фреймворке?

Собственно поэтому меня устраивает моя самопись, которую, как вы наконец-то догадались, я не пишу каждый раз с нуля, а тягаю с проекта в проект.

>Будьте уверенны наговнокодить можно на чем угодно.

Просто фреймворки приподносятся как нечто такое, на котором будет писаться только качественный код, типа приучает к чему-то :)
>Смысл в кусках кода, если всех устраивает подход фреймворков?
>Я не говорю, что у меня все круто.
тогда зачем вы так яро пропагандируете свою альтернативно-ориентированную точку зрения? Или вы думаете, что после разговора с вами тот же господин fesor к буям выкинет свой многолетний опыт работы с фреймворками и побежит строгать новый идеальный велосипед? Если уж говорить о своих идеальных велосипедах и конвеере работ, то нормальные люди выбирают фреймворк, на нем пишут свою цмс, к ней пишут кучу всяких модулей которые могут понадобиться, и вот на этой цмс уже клепают сайты. А написать ядро с нуля(пусть и один раз), потом его поддерживать и отлавливать баги и дыры — вы уж меня извините — это дурость и сизифов трудю Как по моему мнению — лучше уж переложить этот труд на разработчиков и комьюнити. Хотя если у вас вагон времени и с десяток сертификатов спеца по компьютерной безопасности — вперед на баррикады

>Во всех фреймворках похожие подходы…
может быть это чего-то да значит, не задумывались? ;)

>как вы наконец-то догадались
то что вы её тягаете из проекта в проект все знали изначально, вам скорее указывали на то, что вашу самопись в случае каких-то изменений может быть проблематично обновить на тех проектах которые вы уже реализовали с её помощью(это нужно не всегда, но тем не менее)

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

>нормальные люди выбирают фреймворк, на нем пишут свою цмс, к ней пишут кучу всяких модулей которые могут понадобиться, и вот на этой цмс уже клепают сайты

А не проще взять готовую CMS?

>А написать ядро с нуля(пусть и один раз)

Это не так и сложно.
Мое ядро всего 50 КБ.

>может быть это чего-то да значит, не задумывались? ;)

Они все пошли по ложной дороге.

>вашу самопись в случае каких-то изменений может быть проблематично обновить на тех проектах которые вы уже реализовали с её помощью(это нужно не всегда, но тем не менее)

С обновлениями моей самописи проблем нету.
На всех сайтах всегда последняя версия, правда обновления не автоматические, а полуавтоматические.
С обновлениями самописей вообще могут быть проблемы, как у меня на одной работе, где у каждого клиента было свое ядро.

>Вы свою точку зрения преподносите так же.

Это только из-за того, как преподносятся фреймворки.
Я не говорю, что на самописях только качественный код, я говорю, что качественный код возможен не только на фреймворках, но и на самописях.
И я говорю не столько о коде, сколько о принципах.
И не столько о самописи, сколько о глупых принципах фреймворков.
Самопись выступает как альтернатива, когда все вокруг сошли с ума.
Это только из-за того, как преподносятся фреймворки.


А как они преподносятся? Они преподносятся как инструменты для решения проблем. То что люди начинают зацикливаться на них это проблема людей. Это как с языками программирования, есть фанаты и все тут. Рассматривать другие языки они даже не будут, хотя для профессианального развития нужно знать хотя бы парочку очень разных языков с разными подходами.
И не столько о самописи, сколько о глупых принципах фреймворков.


У вас есть опыт работы только с Yii. А там большая часть "принципов" программирования нарушены в угоду скорости разработки. О каких тогда принципах мы говорим? SOLID дурацкая идея? GRASP?

ну фреймворки вроде симфони или zend же дурацкие, стало быть и SOLID дурацкая концепция.

>> Во всех фреймворках похожие подходы…

https://github.com/zendframework/zend-expressive

тут вас что например не устраивает для инфо?
<sarcasm>а там есть меню и хлебные крошки? без них любой фреймворк гуано и пофигу какая у него история и кто его разрабатывает.</sarcasm>
это вы верно говорите, но все же хотелось бы услышать более компетентное мнение )
Если у вас нету своего ядра, то пользуйтесь фреймворками дальше. :)


ядро означает тот факт, что оно внутри вашего приложения. То есть никакого Inversion of Control. Фреймворки же обычно сверху, снаружи приложения.

Что будет с вашим приложением через 10 лет?
Просто есть куда стремиться…


Вам?
О хлебных крошках и меню я говорю не о шаблонах, а скорее о едином интерфейсе у всех на одном фреймворке.


Что если я вам скажу что тенденция выносить графический интерфейс полностью отдельно в виде SPA только продолжит набирать популярность? И в этом случае серверу об этом париться уже не нужно? Например у меня все проекты за последние 2.5 года с SPA или мобильными приложениями, "хлебные крошки" и любая навигация реализуются уже на клиенте.
>ядро означает тот факт, что оно внутри вашего приложения. То есть никакого Inversion of Control.

Ядро отдельно, пользовательский код отдельно…

>Что будет с вашим приложением через 10 лет?

Одному сайту уже 8 лет.

>Вам?

Создателям фреймворков
Но они и их адепты считают, что все норм :)

>Что если я вам скажу что тенденция выносить графический интерфейс полностью отдельно в виде SPA только продолжит набирать популярность?

Не знаю, что такое SPA.
Но я говорил не о графическом интерфейсе, а об АПИ.
4 статьи в которых все разжевано до мелочей. мне очень понравилось знакомиться с фреймворком
>Чтобы инвертировать, нам нужно обновить сущность Blog так Doctrine 2 будет знать, что запись может содержать много комментариев. Обновите сущность Blog src/Blogger/BlogBundle/Entity/Blog.php

Хм, а если нам нужно привязаться к сторонней сущности, то нужно править исходники, которые перезатрутся от обновления?

А теперь давайте рассуждать… С какой стати сторонняя сущность должна что-то знать о вашей? Она же на то и сторонняя что бы ничего этого не знать.


Ну и потом, как правило сторонние пакеты предоставляют базовую реализацию сущности, оставляя возможность заменить своей (сущности — это бизнес объекты, а бизнес объекты не должны зависить от внешних зависимостей) или расширять.

В моем ядре сущности не знают друг о друге абсолютно ничего, но это не мешает делать между ними связи.

А на фреймворках такая печальная ситуация, что связи со сторонними сущности не сделаешь :)

Вообще наличие этих прописанных связей плохо пахнет.

Комментарии ничего не должны знать о постах и наоборот.

>а бизнес объекты не должны зависеть от внешних зависимостей

Я не понимаю этой фразы… :)

У фреймворков есть маркетплейс, например, как в Битриксе?

>оставляя возможность заменить своей

Написать с нуля? Или отнаследоваться?

С нуля писать наверно плохо. Это потом придется поддерживать актуальность. Это дублирование кода. И есть заповедь: Не плоди сущностей. :)

Наследование? Где будем сохранять ее? В своем бандле? Аннотации (комментарии) не наследуются.
В моем ядре сущности не знают друг о друге абсолютно ничего, но это не мешает делать между ними связи.

В "ядре" не должно быть сущностей. Ну и если у вас есть связи, то они должны знать друг о друге либо сверзу будет объект хранящий свящи и управляющий этим всем.


А на фреймворках такая печальная ситуация, что связи со сторонними сущности не сделаешь :)

Вы можете указать связь вашей сущности со сторонней, но сторонняя не должна ничего знать о вашей сущности. И с этим в "фреймворках" проблем нет. Ну и опять же — мы сейчас говорим даже не о фреймворках а о ORM, которые нужны даже не в 90% случаев.


Вообще наличие этих прописанных связей плохо пахнет.

Давайте отстранимся от фреймворков и PHP на секундочку и вспомним о такой забытой штуке как UML. И представим что мы не проектируем "архитектуру" а просто сидим с клиентом и он объясняет как у него сейчас построен процесс или как он хочет что бы оно работало. Он вам рассказывает:


Ну… у меня есть товары, которые хранятся на складе. Складов у нас несколько, и нужно знать какой товар на каком складе. Причем товары могут перемещать со склада на склад (логистические загоны)… Этим занимаются управляющие складом.


То есть мы видим что склад должен знать о том, какие продукты в нем хранятся. И следовательно у сущности склада будет свойство products в котором будет храниться коллекция всех продуктов на этом складе. Логично? Так мы можем прямо в сущности реализовать метод для проверки есть ли на складе столько продуктов, можно организовать резервирование оных и т.д.


Я не понимаю этой фразы… :)

Есть такой подход к проектированию, который собственно исповедует Doctrine. Наши сущности — это просто PHP объекты, которые ничерта не знают ни о доктрине, ни о симфони… Они просто хранят какое-то состояние и поведение. Объекты предметной области. Например объект склада умеет хранить продукты, умеет их резервировать и все такое. Но трансфер между складами уже за рамками обязанностей одного склада и подобную логику нужно выносить на уровень выше.


А вся инфраструктура — фреймворки, работа с базой данных, весь технический булшит, оно все в сторонке. Этот подход выгодно использовть тогда, когда у вас предметная область не тривиальна как например с бложиком. Что-то уровня интернет магазинчика или там логистический центр.


К сожалению подавляющее большинство разработчиков выносит поведение из сущностей в менеджеры, и сущности превращатюся в тупые хранилища данных. Тем самым мы снижаем зацепление наших объектов, ломаем принцип единой ответственности и усложняем взаимодействия, как минимум нарушаем инкапсуляцию частенько. Просто так, на ровном месте. Но это проблема не фреймворков а людей.


Написать с нуля? Или отнаследоваться?

it depends. Например взять FosUserBundle. Для простеньких проектов можно отнаследоваться, а для проектов посложнее можно написать полностью свою реализацию (когда переопределение выходит не так гибко). Сам же FosUserBundle ожидает любую сущность имплементирующую AdvancedUserInterface так что никаких проблем с поддержкой.


Аннотации (комментарии) не наследуются.

наследуются свойства. А стало быть если вы не переопределяли свойства — то наследуются и аннотации.

>В «ядре» не должно быть сущностей.

Они и не в ядре. Просто ядру не нужно описание связей.

>ORM, которые нужны даже не в 90% случаев

Может не нужны в 90% случаев. У меня нету ОРМ.

>То есть мы видим что склад должен знать о том, какие продукты в нем хранятся.

Если не использовать ОРМ, то никто ничего не должен знать :)

>К сожалению подавляющее большинство разработчиков выносит поведение из сущностей в менеджеры, и сущности превращатюся в тупые хранилища данных.

В мире веб у сущностей и не должно быть поведения. Есть только выбор элементов, но и его пихать в сущность не стоит. Я за тупые хранилища данных.

И многие разработчики держат выбор элементов в сущности (Yii это даже считает лучшей практикой :) Не знаю, как другие), ну или создают одноразово используемые тупорылые методы вроде get10LastNews() например в контроллере.

>А стало быть если вы не переопределяли свойства — то наследуются и аннотации.

А как мы добавим связь, не переопределив свойство?

В мире веб у сущностей и не должно быть поведения.

Нет никакого мира WEB. Мы сейчас говорим про серверную часть в контексте клиент-серверной архитектуры. Это одно приложение. Оно может даже ничего не знать о WEB (представьте что у вас просто CRON-ом дергаются скрипты). Для приложения нет разницы запускаются ли команды через cron, выполняются из очередей или же по HTTP запросу. Как только мы перестаем думать мысли в духе "это web тут наверное по другому", все становится намного проще.


Ну и собственно когда у сущностей нет поведения, это называется анемичной моделью и признано антипаттерном. Почему антипаттерном? Потому что вам все еще нужно описывать эту модель но она никакой пользы вам не дает. Тот код который можно было писать прямо внутри сущности мы выносим в какие-то другие вещи, и при этом дергаем кучи сеттеров.


Как итог — читая код вы не сможете быстро понять какие бизнес-ограничения налагаются на ваши сущности. То есть вам придется в разы больше времени потратить что бы разобраться в предметной области по коду (например когда вы вводите нового разработчика в проект или просто работаете с проектом который писали год назад).


Есть только выбор элементов, но и его пихать в сущность не стоит. Я за тупые хранилища данных.

А что такое элементы в контексте вопроса? Я правильно понимаю что вы про такие штуки (в контексте Yii):


Something::findStuff(); // так?

Это просто для удобства. Этот метод на самом деле не пренадлежит сущностям/моделям — он же статический, то есть это просто функция закрепленная за каким-то типом. Внутри оно дергает глобально доступные штуки и т.д. но вам никто не мешает делать отдельный объекты, которые занимаются выборками. Это более правильный подход просто в большинстве случаев это оверхэд. Но знать что так можно несомненно надо.


Так же между AR в Yii (и другие реализации) и Doctrine есть одна огромная разница:


Doctrine оперирует объектами, и мэпит их на базу данных. То есть один объект можно замэпить хоть на 10 таблиц или 10 объектов замэпить на одну таблицу. Тогда как в случае с AR наши "модельки" это прямая проэкция рядов таблиц.


В случае AR ответственность за управление рядом таблицы лежит на самой моделе. В случае Doctrine "модельки" ничерта не знают о базе данных и вводится объект-репозиторий, который и является "тупым хранилищем". В нем максимум можно расположить логику, ограничивающую можно ли ложить объект в репозиторий или нет.


ну или создают одноразово используемые тупорылые методы вроде get10LastNews() например в контроллере.

Ну печально. У меня в репозиториях будет метод getLatestNews($limit = 10)


А как мы добавим связь, не переопределив свойство?

Повторюсь еще раз. Если мы наследуемся от сторонней сущности, там нет связей с нашими сущностями потому что… ну сторонний пакет понятия не имеет о том кто и как будет его использовать.


А если связи нет и хотим ее добавить, то мы добавляем свойство а не "переопределяем".

>признано антипаттерном

Божественный объект тож признан антипаттерном, но jQuery это не мешает :)

>Потому что вам все еще нужно описывать эту модель но она никакой пользы вам не дает.

А я у себя ее и не описываю. 3 строчки кода для наследования базового класса, где указана таблица, с которой работать и все :)

Я не разделяю жирных моделей. Все должно быть просто. Какое поведение в вебе? Выбрать из базы и записать в базу. Неоходимо грамотное АПИ для этого, а не тонны лишнего кода.

Или письма отправлять из сущностей? :)

>А что такое элементы в контексте вопроса?

Записи в БД (результаты запросов).

Я против методов get10LastNews и get10FirstComments (ну или без 10, например, getLastNewsByAuthor)

>Если мы наследуемся от сторонней сущности, там нет связей с нашими сущностями потому что…

У стороннего пакета могут быть связи сущности с его сущностями.
jQuery совсем из другой области. Да и по большей части это неймспейс уже.
Божественный объект тож признан антипаттерном, но jQuery это не мешает :)

а где там god object? Там все весьма грамотно.


3 строчки кода для наследования базового класса, где указана таблица, с которой работать и все :)

И тогда мы говорим не о "моделях", "сущностях" и т.д. а о старом добром row data gateway.


Я не разделяю жирных моделей. Все должно быть просто.

Все должно быть в меру. Тощие модели тоже никто не любит. Они должны быть сочными но не жирными. Что бы было за что ухватиться, но что бы проходили в дверь.


Если модель слишком жирная — значит декомпозиция системы проведена плохо и "модель" нужно дробить.


Или письма отправлять из сущностей? :)

Это другая крайность. Чисто теоритически через дабл-диспатч и свои интерфейсы (то есть мы передаем сервис реализующий интерфейс, лежащий рядом с сущностью, в качестве аргумента какого-то метода этой сущности) в этом даже не будет ничего плохого. Но мне больше нравится комбинация domain events + event dispatcher для подобного либо просто явно задавать эти действия в сервисах уровня приложения.


Записи в БД (результаты запросов).

конкретно вы говорили о чтении из БД. Запись в БД в контексте active record это как раз таки дело самой модели. Если вам не нравится и нужен именно ORM — то доктрина (или любой датамэппер) хороший выбор. А если не нужен ORM — лучше использовать table gateway.


Я против методов get10LastNews и get10FirstComments (ну или без 10, например, getLastNewsByAuthor)

размажем SQL повсюду? Где-то же это должно быть изолировано? А стало быть и методы такие появятся. Вопрос только в том, где они будут расположены и насколько нам будет удобно это тестировать и использовать.


У стороннего пакета могут быть связи сущности с его сущностями.

Могут быть конечно. Но зачем вам их переопределять? В любом случае доктрина предоставляет возможность переопределять мэппинги так гибко.

>конкретно вы говорили о чтении из БД

«Записи» — не процесс записи, а строчки в таблице. :)

>row data gateway, table gateway

Тут описание какое-то унылое: :)
http://www.design-pattern.ru/patterns/table-data-gateway.html
http://www.design-pattern.ru/patterns/row-data-gateway.html

У меня же нормальное АПИ для работы с БД, ну и пофиг, что для него нету умного термина :)
Ну или термин есть, но у них реализации унылые, а у меня норм :)

>размажем SQL повсюду?

Изолировано должно быть, но без таких методов :)

>Но зачем вам их переопределять?

Не переопределять, а добавить. Связывание не по первичному ключу, а по двум вторичным. Если предоставляет, то ок :)
У меня же нормальное АПИ для работы с БД, ну и пофиг, что для него нету умного термина :)

Покажите. Ибо я могу судить только по этому примеру: http://govnokod.ru/19878#comment323654


И называется это процедурное программирование без явного разделения ответственности. Просто говнокод. Вполне себе академический термин :)


В целом же подозреваю что вы организуете DAO или другими словами Table Gateway + кастыли.

К сожалению подавляющее большинство разработчиков выносит поведение из сущностей в менеджеры, и сущности превращатюся в тупые хранилища данных.


Отчасти это связано с некоторыми особенностями Doctrine. Например, в сущность сложно заинжектить сервис, особенно лениво.

в сущности не стоит инджектить сервисы, как по мне. А передать сервис через дабл диспатч — без проблем.

Не вижу смысла для данной задачи ни создавать CommentRepository, ни получать их отдельно в контроллере, ни передавать их отдельно в шаблон. По данной задаче комментарии не являются самостоятельными сущностями, они лишь агрегат в блоге. Наивная (и академически чистая :) реализация могла бы сводиться к методу getApprovedComments в Blog:
public function getApprovedComments() 
{
  return $this->comments->filter(function (Comment $comment) {return $comment->getApproved()})
}
, который вызывался бы непосредственно в шаблоне, а потом, при оптимизации создать метод в репозитории блога (как корня агрегата), который получал бы из базы блоги только с утвержденными комментариями.

Кстати о комментариях. Имена типа $comment->getComment() обычно неудобны и сбивают с толку и в коде, и в базе (comment.comment). Лучше использовать text, body, content, в конце-концов просто value. А булевы поля для статуса записей быстро себя исчёрпывают, в частности уже сейчас если поле approved === FALSE, то нельзя однозначно сказать, то ли уже одобренная запись была разодобрена, то ли это новая, которую ещё не просматривали, то ли просмотрели и отклонили.

Да, даже если остановиться на булевом поле, то по соглашениям для таких полей имя isApproved, а не approved, что гораздо понятнее. Кстати, тогда Doctrine и метод сгенерирует не getIsApproved, а isApproved, что удобнее. И если потом перейти к каким-то другим статусам, то можно просто переписать код иззера isApproved() не изменяя клиентского кода. Кстати, ещё по замечание по именованию — принято, что тайстамп поля именуются в мире доктрин/симфони как createdAt и updatedAt, более чётко определяя сущность поля.

маленькая поправка. Можно сделать extra-lazy связь и вместо filter использовать matching с критерией. Тогда сформируется правильный SQL запрос и не придется грузить всю коллекцию. Хотя это мелочи.

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html — про ExtraLazy

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections — про matching.

Очень удобная и крутая штука. Рекомендую.
Ошибка после: $ php app/console doctrine:fixtures:load

Должно быть:
class BlogFixtures extends AbstractFixture implements OrderedFixtureInterface
Теперь мы готовы загрузить фикстуры в базу данных
$ php app/console doctrine:fixtures:load


в этот момент посыпались ошибки типа
SQLSTATE[42601]: Syntax error: 7 ОШИБКА: ошибка синтаксиса примерное положение: "user"

оказало проблема в поле «user», это имя зарезервировано в postgres, пришлось сменить на «uuser» :)
PostgreSQL 9.3
при смене имени. следует учесть это и в шаблонах
{# src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig #}
{# ... #}

{{ comment.uuser }} commented {{ comment.created|date('l, F j, Y') }}


сменить на «uuser»

users тогда уже… ужасные кастыли на ровном месте.


PostgreSQL 9.3

уже как бы 10-ая версия, и судя по контексту вы новый проект делаете.


следует учесть это и в шаблонах

не следует — вы можете название таблицы явно в меппинге указывать, как никак вы ссылаетесь на поля объекта а не на табличку в базе.


Итого — вам не стоит юзать доктрину. А с postgre 9.4+ в целом значительно падает необходимость в подобных инструментах (за счет jsonb, можно целиком стэйт хранить одним полем и отпадает любая необходимость мэпить связи)

Ну и опять же, достаточно обратиться к документации (что вы обязаны делать когда изучаете новый для вас инструмент): Doctrine Documentation: Quoting Reserved Words


Вообще очень плохая идея изучать Doctrine по огрызкам из документации к симфони. И еще более плохая идея — изучать symfony по огрызкам на хабре.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.