Yii, вероятно, самый популярный PHP фреймворк на просторах СНГ.
Многие годы он был замечательным инструментом и помогал нам зарабатывать на хлеб с маслом.
Но стоит ли начинать на нем новые проекты в 2017-м? Я задумался.
Архитектура фреймворка
Мысленно вернемся в 2014-й.
Ожидание второй версии Yii кажется бесконечно долгим, core-разработчики не называют никаких сроков.
Разработка ведется в закрытом от публики репозитории.
И вот SamDark презентует Yii 2.0:
После трёх лет интенсивной разработки...
Как вы, возможно, уже знаете, Yii 2.0 был переписан с нуля.
Выходит, архитектура закладывалась в 2014 — 3 = 2011-м году. Или раньше?
Взгляните на Component.php из Yii 2
А теперь на CComponent.php из Yii 1
А теперь на TComponent.php из PRADO Framework — дедушки нынешнего Yii. Выглядит знакомо.
Истоки самого же PRADO уходят куда-то во времена расцвета Delphi:
The very original inspiration of PRADO came from Apache Tapestry.
During the design and implementation, Qiang Xue borrowed many ideas from Borland Delphi and Microsoft ASP.NET.
The first version of PRADO came out in June 2004 and was written in PHP 4.
С первой версии нам достались глобальные константы в коде, свой autoloader, своя хитрая система алиасов для файлов и папок.
Ооооок. Просто напоминаю, что сейчас идет вторая половина 2017-го.
Приходя к Yii с других инструментов, вы должны понимать, что здесь весь ваш предыдущий опыт становится нерелевантным.
Yii — это не просто фреймворк, это попытка сделать свою надстройку над языком.
Все, абсолютно все компоненты Yii наследуются от класса Object, в котором переопределяются __get
, __set
, __isset
и так далее.
Многие классы наследуются от Component, который наследуется от Object, и в котором еще раз переопределяются все магические методы.
Благодаря этому все классы фреймворка из коробки умеют бросать события, подписываться на них, могут содержать т. н. behaviors.
Каждая модель ActiveRecord в вашем приложении неявно наследует 5 классов и реализует 5 интерфесов.
У всех ваших моделей, так называемых "компонентов", "виджетов", контроллеров, логгеров, хелперов, валидаторов — одни и те же предки.
Компоненты, их события, поведения… возможно, они имели смысл в PRADO Framework, где "компонентами" были TButton, TAccordion и все вот это.
Среди достоинств Yii часто озвучивают простоту фреймворка. Но это правда только отчасти.
Знаете, что происходит, когда вы делаете что-то безобидное вроде $post->title = 'Hello'
?
Вы можете побывать здесь, здесь, здесь, здесь, а также в любом прикрепленном к $post event-у или behavior-у.
Это может свести с ума во время отладки.
Не добавляет радости и тот факт, что любой компонент приложения из любого места можно достать через Yii::$app. Эдакий экземпляр приложения и сервис-локатор в одном лице.
DI-контейнер
В Yii 2 он есть.
В нем нет ни compile-time проверок, ни защиты от circular references, ни тегов (как в Symfony и Laravel), ни Contextual Binding (как в Laravel).
Доступен из любой точки приложения как Yii::$container. Снова.
Внутри Yii 2 собственный контейнер не используется, а все компоненты лежат в Yii::$app, прямо как в первой версии.
Интересный факт: Qiang начал писать Yii 2 в 2011 году, а контейнер был добавлен только три года спустя, между 2.0.0-alpha и 2.0.0-beta.
Active Record
Если оставить в стороне споры Active Record vs Data Mapper, то реализация AR в Yii очень даже ничего.
Удобное и лаконичное API, поддерживаются все популярные СУБД. Есть нормальные миграции из коробки.
Единственный минус вытекает из сильной связанности фреймворка — если ваша бизнес-логика оказалась в AR-моделях, то переиспользовать все это добро можно только в рамках проектов на Yii.
Фронтенд
Тут все плохо.
В Laravel есть Elixir, в Symfony с недавних пор — Webpack encore.
Yii же не просто не помогает с фронтендом, а еще и добавляет головной боли.
Для установки Yii 2 вам нужно в принудительном порядке поставить глобально fxp/composer-asset-plugin, для того, чтобы поставить jQuery c помощью composer-а, для того, чтобы установился Yii.
jQuery входит в обязательные зависимости Yii 2.
Не припоминаю ни одного другого composer-пакета, для установки которого нужно было танцевать с бубном.
В проектах с Yii каждый запуск composer install/update
происходит утомительно долго,
т.к. composer каждый раз идет гулять куда-то в глубины репозитория Bower-пакетов.
Еще мне когда-то пришлось откатывать версию composer-а на более старую, из-за несовмесимости с текущей версией fxp/composer-asset-plugin.
В качестве альтернативы предлагается использовать дополнительный composer-репозиторий, который кеширует npm и bower пакеты. Что тоже выглядит немного костыльно.
Если знаете, как поставить Yii без возни с ненужными фронтенд-пакетами — пишите в комментариях.
Все остальные компоненты
Абстракция над HTTP, кеширование, логирование… они есть, и они без проблем выполняют свои задачи.
Конечно же они самобытные, гвоздями прибитые к Yii, и не имплементируют соответствующие им PSR-ы.
Будущее Yii
Скорость развития оставляет желать лучшего
Помните, как долго мы ждали версию 2.0?
А вы знаете, когда выйдет 2.1? Никто не знает.
2.0.x: 222 открытых тикета — No due date.
2.1.0: 58 тикетов — No due date.
2.2.x: 1 тикет — No due date.
Т.е. для 2.1 еще не определена дата релиза, а для 2.2 даже примерный скоуп задач. До третьей версии, о которой еще рано даже начинать говорить, мы вряд ли увидим кардинальные изменения в архитектуре.
Следует признать, что ближайшие конкуренты — Laravel и Symfony — внедряют новые фишки и выпускают версии гораздо резвее. У обоих конкурентов уже есть LTS-версии. Yii 2.1 вроде бы тоже должна иметь long-term support.
Компонентные фреймворки победили
Если кто-то напишет хорошее расширение для Yii — оно не выйдет за пределы комьюнити Yii.
Библиотека же, которую можно подключить без бубна к любому проекту, может улучшаться кем угодно.
Код, написанный на PHP, работает везде, а код, написанный на Yii — только на Yii.
Вы либо ставите на Yii всё, либо ничего. Это риск для долгосрочного проекта.
Конечно, приложив усилия, можно писать framework-agnostic код и разруливать все через DI-контейнер, но это не поощряется.
Если вы все-таки решитесь на это, вам прийдется забыть про Yii-вский ActiveRecord
или начать писать неприлично толстые прослойки между фреймворком и вашей бизнес-логикой.
Но это, мягко говоря, неоправданно.
Если вы наследуете какой-либо класс своего приложения от любого другого класса Yii, без Yii вы его работать не заставите, ведь он обязательно наследует Object или Component. Вот.
Даже если вы вытащите вместе с ним весь ворох родительских классов и реализуемых интерфейсов, это вам не поможет.
С модными нынче DDD и CQRS/Event Sourcing Yii также вам не помощник. Скорее, даже будет вставлять палки в колеса.
Команда фреймворка всё пишет сама. Даже VarDumper они написали свой, а не взяли из компонентов Symfony.
Регулярно поддерживать и улучшать столько компонентов — очень непростая задача для небольшой команды. И у этой команды есть два пути.
Во первых, можно оставить все как сейчас.
Все компоненты пишем сами. Сильная связанность. Полностью изолированная экосистема фреймворка. Небольшое уютное комьюнити. Медленная деградация.
Во-вторых, можно все-таки разбить монолитный Yii на независимые от фреймворка компоненты.
Но тогда это будет уже не Yii с простым и удобным API, а просто еще один набор компонентов, не востребованный вне экосистемы Yii.
Оба пути ведут в никуда.
PHP 7
Yii 2 без проблем работает под PHP 7+.
Однако чтобы использовать все возможности type-hinting-а, core-разработчикам придется переписать его до неузнаваемости.
Дело в том, что сейчас много методов принимают аргументы нескольких типов:
// Поиск записи по первичному ключу со значением "42"
SomeModel::findOne(42);
// так тоже работает
SomeModel::findOne(['id' => 42]);
// Вернет первую найденную запись, у которой PK - одно из значений переданного массива
SomeModel::findOne([1, 2, 3]);
// и так можно
Url::to(['site/index']);
// и так
Url::to('images/logo.gif');
// или вот
$relativeBaseUrl = Url::base();
$absoluteBaseUrl = Url::base(true);
$httpsAbsoluteBaseUrl = Url::base('https');
Таких мест в фреймворке очень много. Кого-то это бесит, кто-то считает это API удобным.
Но если мы хотим использовать тайпхинтинг, все это удобное API превращается в тыкву.
Qiang так и не вернулся
Полтора года назад на форуме Yii подняли интересный вопрос, мол, не забил ли Qiang Xue на свое детище?
Как бы там ни было, с тех пор от него так и не пришло ни одного коммита.
Возможно этот факт ничего не значит.
В любом случае поддержкой фреймворка сейчас занимаются замечательные ребята, и они хорошо справляются.
Что в итоге
Yii — неплохой инструмент и если вам с ним комфортно — отлично.
В конце-концов, он практичен. Трудно представить задачу, которую невозможно решить, используя Yii.
Еще Yii невероятно популярен в СНГ. Зная его, очень легко найти как работу, так и сотрудников.
Но если у вас намечается новый долгосрочный проект, обязательно рассмотрите альтернативы.
Не выбирайте инструмент только из-за привычки.
Кроме того, вы всегда можете помочь команде фреймворка. Присылайте внятные баг-репорты, отправляйте пул-реквесты, пишите качественные расширения, помогайте новичкам на форуме и в gitter-е.
Может быть, Yii еще покажет себя ;)
Комментарии (271)
Samouvazhektra
16.07.2017 19:55+1Yii хорошо соответствует требованию нашего рынка — не все готовы платить за DDD и Symfony, и нужно это далеко не везде, и в принципе для заказчика в конечном итоге в основном пофигу что под капотом, а проектов серьёзного уровня с серьёзным подходом в соотношении со средними и небольшими гораздо меньше.
AlexLeonov
16.07.2017 19:59+7Yii хорошо соответствует требованию нашего рынка — не все готовы платить за DDD и Symfony, и нужно это далеко не везде
Можно я перефразирую немного?
«Не все готовы платить за нормальных программистов, поэтому нанимают людей, не способных разобраться в простейших концепциях программирования, ведь им можно платить меньше — и пофигу на результат.»
Кажется, что так смысл будет выражен точнее :)Samouvazhektra
16.07.2017 20:05+4А для клиента который ни в зуб ногой, что нормальный, что не нормальный программист — выглядят одинаково.
Они могут и не видеть этого программиста — они идут в студию и их встречает менеджер.Fesor
16.07.2017 20:43+2выглядят одинаково.
Если мы говорим про сайты визитки — то да. Но обычно когда клиент у вас просит что-то подправить а у него отламывается функционал и вообще все медленно пилится — он может ужа начинать что-то подозревать.
SamDark
16.07.2017 20:55+2Только это, скорее, про тесты и архитектуру, а не про фреймворки...
AlexLeonov
16.07.2017 21:03+2Это, скорее про принципиальную возможность писать бизнес-логику в afterSave(), чем разумеется, большинство «студий» с огромной радостью пользуется.
Не было бы такой возможности — не было бы половины того говнокода, что я видел в своей жизни.
И да, это, конечно же, про архитектуру. Только зачем эта архитектура заложена в фреймворк?SamDark
16.07.2017 21:05+7Принципиальная возможность напихать логику куда угодно есть в каком угодно фреймворке. Это не означает, что её туда необходимо пихать...
AlexLeonov
16.07.2017 21:14Расскажите мне, как в концепции request -> [middleware] -> response и при неактивных моделях данных я могу напихать что-то «куда угодно»?
SamDark
16.07.2017 21:32+3Неактивные — это entity с репозиторием? Ну, в репозиторий, очевидно, напихать.
А так, например, можно устроить beforeSave() в той же Doctrine. Не раз видел:
/** * @PrePersist */ public function beforeSave() { // колбасим }
AlexLeonov
16.07.2017 21:35+3Экзотичный пример, конечно, но принимаю :) Что-то ржу )))
Не видели никогда, к примеру, вот такое поделие: http://punbb.ru/?
Сферические events в вакууме. Event-driven architecture!
Я к тому, что бесконтрольным использованием системы событий можно убить любой фреймворк. Абсолютно любой.
pbatanov
16.07.2017 21:45+2<zanuda>
s/persist/flush/
</zanuda>
Большая разница в том, что в Yii можно тут сделать что угодно, имея в прямом доступе все компоненты системы через статику, а при работе с symfony+doctrine вы сможете обращаться только к доменной логике (логике модели и ее связей)SamDark
16.07.2017 21:51+1Ох, опять ужас придётся копи-пастить:
global $kernel; $assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');?
Но что в Yii это сделать в разы легче — факт.
pbatanov
16.07.2017 22:01+3Ну, тут очевидная разница в том, что ваш пример — это глобалы, за которые в приличных конторах бьют линейкой по рукам, и это надо сделать специально, а в Yii — это by design. До глобалов на самом деле не видел, чтобы доходили.
Fesor
16.07.2017 22:28+2Можно пойти дальше и прокинуть entity manager в сущность и сделать у сущности метод
save
. Да и доктрина сама по себе не идеал.pbatanov
16.07.2017 22:32Эта возможность, кстати заложена в доктрине из коробки :)
Тем не менее такой подход гораздо удобней, так как не накладывает никаких ограничений на цепочку наследования. Можно сделать ModelTrait и внедрять его везде где очень хочетсяSiddthartha
17.07.2017 02:12трейты это goto для ООП. )
stanislav-belichenko
17.07.2017 05:46Если не секрет, то почему вы так считаете?
Fesor
18.07.2017 11:05+6Для того что бы ответить на этот вопрос стоит для начала разобраться чем плохи эти самые goto и почему они considered harmful. На эту тему рекомендую почитать вот эту штуку: Go To Statement Considered Harmful:
A Retrospective
Если коротко — наши мозги плохо заточены под процессы развивающиеся во времени, мы плохо их прокручиваем в голове. В идеале мы хотим чтобы поток управления кодом шел в том же порядке, в каком он и написан. С goto мы вынуждены "прыгать" по исходникам вверх-вниз дабы собрать всю картину и разобраться "как это работает" или "а где проблема".
Тут следует заметить что существуют задачи где goto прекрасно ложатся на ментальную модель выполнения кода — конечные автоматы. Там они очень даже упрощают и реализацию и понимание происходящего. Потому goto не зло, зло это применение их просто так.
Как ответ на эту проблему появилось структурное программирование, которое дает возможность заменить goto на управляющие структуры —
if
/for
/while
и тд. Затем появились классы и модули (Simula и Modula) которые вводили новые штуки для получения "структур" для декомпозиции системы. Далее Аланы Кеи и друзья решили развить идею в сторону actor model и сотворили smalltalk, где приложение представлено как децентрализованный граф объектов обменивающихся сообщениями. Сегодня самый близкий этой идее язык из тех что я знаю — Erlang.
Так вот, если мы посмотрим на трэйты — они не влияют на типы объектов. То есть, если упрощать, это тупая копипаста кода. То есть код вы может быть и вынесли в трейт, но он по сути принадлежит тому типу, где используется. И если у вас 10 типов используют 1 трейт, это значит у вас нарушена декомпозиция в 10-ти местах.
Тут опять же стоит заметить что проблемы с трейтами возникают только тогда, когда в них хранится поведение. Тупой код-бойлерплейт не влияющий на поведение объекта прекрасно ложится на ООП. А вот когда у нас поведение плохо декомпозировано и оно вылазит в трейты, это создает ту же проблему что и goto. Только если с goto у нас проблемы во флоу управления, то с трейтами — в управлении зависимостями.
Что бы составить полностью картину как работает объект и его поведение нам приходится прыгать по коду. И чем больше трейтов — тем сложнее. Намного выгоднее будет просто разделить это все на отдельные объекты, воспользоваться прокси-объектами и т.д. Трейты тут все еще могут быть полезны как промежуточный этап при рефакторинге например, но только что бы ускорить процесс. В конце этого процесса трейты с поведением должны быть удалены.
stanislav-belichenko
18.07.2017 11:18Понятно, то есть все-таки нет прямой связки между goto и трейтами, а есть лишь подобие в некоторых случаях. Плюс к упомянутому вами выносу всяких вещей, которые не реализуют логику, есть вариант, когда не 10 классов используют 1 трейт, а наоборот, один класс, в зависимости от разных ситуаций его применения, использует 10 трейтов. Например, есть класс, реализующий логику отправки неких данных из одного API в несколько других, и каждое использование этого класса проводится как наследование от базового и включение в себя некоего трейта для того или иного API. Понятно, что это можно реализовать и иначе, но иногда проще и понятнее именно так.
Siddthartha
18.07.2017 15:33аналогия прямая: использование goto прямо, грубо (как еще сказать) нарушает процедурную модель так же, как использование trait — объектную модель. использовать их стоит ровно с той же предусмотрительностью что и в случае goto.
AlexLeonov
18.07.2017 15:44Осталось запретить директиву include в Си, и будет полное объектно-ориентированное счастье на всей Земле :)
stanislav-belichenko
18.07.2017 16:48Как вам выше верно и заметили, осталось весь код теперь писать в одном файле и будет счастье. В общем — нет уж, извините, но аналогия далеко не прямая и полная.
Siddthartha
18.07.2017 17:24+1да прямая она. при чем тут инклуд. цель не полная, а непротиворечивая объектная модель в любом конкретном процессе разработки — а трейты получаются антипаттерном в силу "как выше верно заметили" "внедрять его везде где очень хочется".)) ну, как скажете. не полная, так не полная. но уж прямая точно.
stanislav-belichenko
18.07.2017 17:34Если я верно понимаю, что вы пишете, то вы просто зациклились на использовании трейтов как некоем общем коде для некоторых классов или других вещей. Но это же не так.
Siddthartha
18.07.2017 19:01мм не, я говорю в целом о сути проблемы трейтов, а Fesor привел один из примеров. я скорее о результате get_called_class(), молчаливому перекрытию любых методов в какой бы класс мы его не закинули, конфликтах и т.п. вытекающих последствиях из смысла.
а смысл раскрыт и в первом моем посте и детальнее во-втором. трейт — это хак объектной модели и использовать его только как-то ad-hoc
stanislav-belichenko
19.07.2017 10:53Трейт — это хак файловой системы, когда проще разнести логику по файлам. Не более.
Fesor
19.07.2017 13:39хак файловой системы
Вы дробите проект по файлам или классам? Тот факт что у вас из-за PSR-2/PSR-4 имя класса привязано к файловой системе — это лично ваш выбор. PHP сам по себе вас в этом не ограничивает. Так что трейты к файловой системе никакого отношения не имеют.
Трэйты — это способ устранения дублирования кода каших классов. Как минимум потому что использоваться они могут только в контексте классов а не просто файлов.
Для разнесения именно логики у вас уже есть неплохие структурные единицы кода — классы. Тот факт что вы не можете это сделать без необходимости плодить дублирование одной и той же логики в нескольких классах — это симптом другой проблемы, трейты тут только помогут вам спрятать эти симптомы что бы они вылезли снова когда уже будет слишком поздно что-то с этим делать.
Просто задумайтесь. Если вы не согласны — просто приведите мне примеры где вы считаете "по другому никак" или даже "по другому неудобно". И тогда будем конструктивно обсуждать.
VolCh
19.07.2017 15:53Трейты удобны для базовых реализаций интерфейсов, прежде всего общего назначения типа ArrayAccess. Множественного наследования нет же.
symbix
19.07.2017 16:00-1В Java 8 это решено элегантнее — там есть default methods в интерфейсах.
oxidmod
19.07.2017 16:19В шарпе вроде с 7 версии тоже. Но что это за интерфейс содержащий дефолтную реализацию?
VolCh
19.07.2017 16:37Интерфейс не содержит :) Но если интерфейс реализуют десятки классов и у 90% реализации одинаковые, то трейты удобнее. Например, различные виды сериализации. Или нестандартные для объектов методы доступа. Итеративность. Событийность. Много всего, что не относится к бизнес-логике.
Fesor
19.07.2017 18:51Но если интерфейс реализуют десятки классов и у 90% реализации одинаковые, то трейты удобнее.
Чаще просто что-то не так с декомпозицией и вот эти 90% должны быть в другом классе. Не всегда, но в большинстве случаев когда применяют трейты.
Те же дефолтные реализации методов в java появились как следствие решения проблем обратной совместимости, нежели концепт без которого прям нельзя жить.
symbix
19.07.2017 20:32Вот, кстати, не знаю, зачем это надо в языках, где есть generic-и. В php я пары "интерфейс-трейт" использовал как "дженерики для бедных".
Fesor
19.07.2017 21:50В таком случае рекомендую почитать например эту заметку.
tl;dr
Suppose Java 8 is out and has lambdas. Now you would like to start using lambdas and the most obvious use case for that is to apply a lambda to every element of a collection.
The forEach isn’t declared by java.util.List nor the java.util.Collection interface yet. One obvious solution would be to just add the new method to the existing interface and provide the implementation where required in the JDK. However, once published, it is impossible to add methods to an interface without breaking the existing implementation.
Fesor
19.07.2017 18:45Ну та же идея что и у дефолтных методов интерфейсов в java. Убрать тупой бойлерплейт не влияющий на поведение реализации.
Fesor
19.07.2017 12:58использовании трейтов как некоем общем коде для некоторых классов или других вещей. Но это же не так.
а как же? это их собственно основная идея.
Fesor
19.07.2017 12:40О чем вы вообще? декомпозицию никто не отменял. Я как-то не могу проследить логическую цепочку ваших умозаключений. Может объясните?
Fesor
19.07.2017 12:37прямой связки между goto и трейтами, а есть лишь подобие в некоторых случаях.
Вы знакомы с таким словом как "аналогия"? Трейты усложняют восприятие кода за счет того что ломают информацию о зависимостях и скрывают проблемы декомпозиции. goto усложняют восприятия кода за счет того что ломают поток управления кодом и скрывают изменения стэйта.
То есть и то и то — не зло, но при неправильном использовании можно закончить с весьма сложным и запутанным кодом. goto мы худо бедно за 40 лет перестали писать (хотя люди все еще в коде бывают ставят
break 2;
) а вот в декомпозицию как не умели так и не умеем.
Fesor
19.07.2017 12:39+1Понятно, что это можно реализовать и иначе, но иногда проще и понятнее именно так.
вот приведите пример когда это проще и понятно и будет предметный разговор. Мой опыт подсказывает что это практически никогда не удобнее и не понятнее и даже если у вас получилось понятно — несколько чейнжж реквестов и коду становится плохо.
Fesor
18.07.2017 11:08лучше взять ProxyManager и реализовать все это добро проксей. Но это тогда уже не active record получится.
kraso4niy
20.07.2017 07:13Не согласен с вами.
Трейт это те же mixin, тоже самое свойство и тоже самое наследование. Если ваша декомпозиция использует наследование, то трейты тут не могут быть причиной неверной декомпозиции: )Fesor
21.07.2017 02:46Трейт это те же mixin, тоже самое свойство и тоже самое наследование.
ни разу.
Если ваша декомпозиция использует наследование
как редкое исключение, чаще агрегацию. В целом за последний год были два-три раза когда наследование было единственным адекватным решением проблемы в контексте вопросов декомпозиции и в целом кода.
Fesor
16.07.2017 22:27+3Согласен, но тогда для yii остается место только в качестве read model. Меня лично больше смущает страсть сообщества yii к велосипедам. Это я ничем объяснить не могу. Вот хоть убей.
SamDark
16.07.2017 22:36+2Я тоже. Одно дело сам фреймворк — в него компоненты удачные перекочевали из тех времён, когда ничего не было. Плюс некоторые запилили с нуля потому как было время на них и могли сделать хорошо. Итеративно улучшать это всё логично потому как оно не хуже альтернатив. Хотя, конечно, временами некоторые части хочется выкинуть и взять что-то, что их переросло. Но обратная совместимость в 2.0 это сделать не позволяет.
Совсем другое дело — проекты. Вот в них чем руководствуются, реализуя с нуля всякое, я не уверен...
zelenin
17.07.2017 02:14+3что из этого продиктовано обратной совместимостью?
https://github.com/yiisoft/yii2-queue — лежало несколько месяцев недоделанное, потому что никто не допиливал базовую итерацию.
https://github.com/yiisoft/yii2-authclient — несколько месяцев никто не трогал нерабочую интеграцию с твиттер
https://github.com/yiisoft/yii2-collection — свеженькие коллекции. фейспалм
https://github.com/yiisoft/yii2-httpclient — качество ужасное, но комбайн в стиле yii
https://github.com/yiisoft/yii2-shell — думаю, это тебе самому хотелось поделиться игрушкой, которую сделал. Не уверен, что ей вообще место под yiisoft.SamDark
17.07.2017 11:04Из этого ничего :)
- queue — фреймворконезависимых очередей нормальных не нашлось. Запилили прототип на хакатоне потому что было интересно, сможем ли. Прототип Журавлёв допилили до прекрасного состояния и расширение мы приютили. При этом он его развивает, мы только помогаем советами и докой, как и помогали пока репозиторий был в его аккаунте. Времени не кушает.
- authclient был с самого начала. Он прилично интегрирован с аутентификацией. Если бы использовали внешнюю либу для OAuth, так и так пришлось бы обёртку делать.
- collection — сильно просили прямо в фреймворке сделать поддержку. Решили сделать в расширении. Это не просто generic-коллекции, там есть и специфичные для AR Yii штуки, которые позволяют работать с базой довольно эффективно, а не вытягивать всё и фильтровать средствами PHP.
- httpclient — обёртка с двумя простейшими дефолтными драйверами. Нужна чтобы, например, можно было бы подменить Guzzle на что-то ещё.
- shell — да, скорее всего так. Но каши не просит, можно и оставить.
doniys_a
17.07.2017 11:36+1SamDark
httpclient — обёртка с двумя простейшими дефолтными драйверами
Вы забыли уточнить с 2-мя уж очень неудобными и деревянными драйверами. Простые задачи он решает, стоит столкнуться с доп контролем — и все, наследуешься и сам реализуешь методы.
Чем вас Guzlle не устроил, не понимаю, зачем вам свой велосипед? Лучше он все равно, как показала практика, не поедет.SamDark
17.07.2017 11:45-1Guzzle не устроил интерфейсом. Есть проект. В нём есть зависимости. Одна зависимость использует Guzzle, вторая — httplug, третья ещё что-то. В итоге у нас натягивается много либ. Если зависимости используют httpclient вместо всего этого, появляется возможность вытаскивать одну либу и собирать только её баги.
p.s. да, PSR-7 сейчас эту проблему решает, но тогда его не было...
zelenin
17.07.2017 12:05+4каши не просит, можно и оставить.
про это и был упрек — у вас все каши не просит, что нужно и что не нужно.
да, PSR-7 сейчас эту проблему решает, но тогда его не было...
это не так. Напомню, что я несколько раз высказывался о недоумении об отсутствии поддержки psr-7 в http-клиенте, даже в рамках issue на гитхабе, после чего выяснилось что Paul Klimov о PSR-7 ни сном ни духом.
PS Дата релиза PSR-7 и первого коммита http-клиента расходятся на 2 месяца, т.е. но уже был в релизе, но даже до релиза он пребывал в стабильном состоянии как минимум год, и поверх него было реализовано куча продуктов (например первый коммит zend diactoros был за 9 месяцев до релиза).
Guzzle не устроил интерфейсом. Есть проект. В нём есть зависимости. Одна зависимость использует Guzzle, вторая — httplug, третья ещё что-то. В итоге у нас натягивается много либ.
так теперь этим третьим "чем-то" будет yii2-http-клиент, и в проекте скоро появится что-то четвертое.
SamDark
17.07.2017 14:48так теперь этим третьим "чем-то" будет yii2-http-клиент, и в проекте скоро появится что-то четвертое.
Вообще идея была в том, что будет использоваться что угодно через интерфейс клиента и, тем самым, не будет зависимости на конкретную реализацию.
Оно, конечно, видно, что сейчас можно просто завязаться на интерфейсы PSR-7 и deprecate-нуть httpclient на версию 2.1. Вероятно, так и сделаем.
SamDark
17.07.2017 14:50zelenin
17.07.2017 15:00да, через три дня после https://github.com/yiisoft/yii2/issues/2953#issuecomment-122309117
Fesor
18.07.2017 11:10фреймворконезависимых очередей нормальных не нашлось
допилить до нормального состояния bernard или enqueue.
фреймворконезависимых
"yiisoft/yii2": "~2.0.10",
zelenin
18.07.2017 12:14+1угу. вместо того, чтобы сделать поверх queue-interop
SamDark
18.07.2017 12:18Что такое queue-interop? Это? https://github.com/queue-interop/queue-interop с 200 инсталлами и 20 звёздочками?
zelenin
18.07.2017 12:25+2да, и это хорошая инициатива сделать фреймворконезависимые очереди, недавно выделенная из https://github.com/php-enqueue < — вот это фреймворконезависимые очереди, а не yii2-queue
SamDark
18.07.2017 12:50Я и не говорил, что yii2-queue фреймворконезависимый. Я говорил, что мы не нашли чего-то, что можно было бы взять за базу.
Hazrat
16.07.2017 20:09-20php фреймворки обрасли ненужной логикой и всякой всячиной, что со стороны смотреть на все это дело сложно, не говоря уже, о том, чтобы что-то на нем написать.
Я благополучно слез с этой сложной машины на легковесный node jsiborzenkov
16.07.2017 20:30+24на легковесный node js
Поперхнулся…
В течении последних двух лет назвать js легковесным…
Слезть с php на ноду из-за легкости — месье знает толк в извращениях.
AlexLeonov
16.07.2017 20:31php фреймворки обрасли ненужной логикой и всякой всячиной, что со стороны смотреть на все это дело сложно
quod erat demonstrandum
paratagas
17.07.2017 12:37+1Node.js в крупном приложении обрастает тьмой модулей и в итоге все равно получается некий кастомный фреймворк со сложной логикой. И эта логика по сложности не уступает логике многих PHP фреймворков «из коробки». А если взять какой-либо «упрощенный» PHP фреймворк, вроде Silex или Slim, то можно изначально получить менее «сложную машину».
RSalo
16.07.2017 21:14+3Оба пути ведут в никуда.
Что-то не смог прочитать «между строк» про пути выхода…
SamDark
16.07.2017 21:45+20Неплохой пост. Частично верный, частично нет. Думаю, стоит немного разобрать.
Архитектура фреймворка
Выходит, архитектура закладывалась в 2014 — 3 = 2011-м году. Или раньше?
Архитектура закладывалась в течение многих лет. Что-то, что показало себя хорошо — перекочевало в немного изменённом виде ещё из Prado, что-то из Yii 1.1, а что-то, что показало себя плохо — было обдумано и разработано с нуля.
Мысленно вернемся в 2014-й. Ожидание второй версии Yii кажется бесконечно долгим, core-разработчики не называют никаких сроков. Разработка ведется в закрытом от публики репозитории.
А вот и нет: https://habrahabr.ru/post/178917/
С первой версии нам достались глобальные константы в коде, свой autoloader, своя хитрая система алиасов для файлов и папок.
Ооооок. Просто напоминаю, что сейчас идет вторая половина 2017-го.
- Константы — да. Будем менять их на getenv или что-то подобное.
- Не понимаю, что плохого в своём полностью PSR-4 совместимом autoloader-е, необходимом для поддержики алиасов и работающем быстрее, чем тот же autoload-ер Composer-а. Если бы он было хуже, тогда нет вопросов — выкинули бы не думая. Напомню, что писался он задолго до релиза Composer. И ещё уточню, что autoload-ер в Yii 2 не имеет ничего общего с autoload-ером Yii 1.1.
- Что плохого в системе алиасов для путей файловой системы и URL тоже не понимаю.
Приходя к Yii с других инструментов, вы должны понимать, что здесь весь ваш предыдущий опыт становится нерелевантным.
Yii — это не просто фреймворк, это попытка сделать свою надстройку над языком.Конечно, зависит от опыта, но знакомые, которые писали на Yii проекты и до этого работали с Symfony, Django, RoR, Spring и т.д. сильных проблем не испытывали. Незнакомый код не в счёт. Изучение при использовании нового инструмента всегда занимает какое-то время. Любой фреймворк даёт надстройку над языком. Свой DSL, упрощающий построение проектов. Иначе какой в фреймворке смысл?
Компоненты, их события, поведения… возможно, они имели смысл в PRADO Framework, где "компонентами" были TButton, TAccordion и все вот это.
Они и сейчас имеют смысл. Да, иерерхия наследования в Yii далеко не идеальная и мысли по сокращению её есть.
Среди достоинств Yii часто озвучивают простоту фреймворка. Но это правда только отчасти. Знаете, что происходит, когда вы делаете что-то безобидное вроде $post->title = 'Hello'?
Вы можете побывать здесь, здесь, здесь, здесь, а также в любом прикрепленном к $post event-у или behavior-у. Это может свести с ума во время отладки.Только если кто-то очень сильно постарается в коде приложения и либо нацепляет очень много нетривиальных behavior-ов, либо сделает всё на событиях. Логика properties очень простая, покрытая на 100% тестами и хорошо документированная.
Не добавляет радости и тот факт, что любой компонент приложения из любого места можно достать через Yii::$app. Эдакий экземпляр приложения и сервис-локатор в одном лице.
Практически в любом фреймворке можно достать глобально и явно контейнер. Но это не означает, что по-другому писать нельзя (в Yii, например, есть нормальный autowiring) и это не означает, что так надо делать.
DI-контейнер
Отстутсвующие фичи из других фреймворков либо настолько редко используются, что никому не нужны, либо просто их никто не просил. Так мы не против допила контейнера, если в этом есть необходимость. Если вам лично нужна какая-то фича, опишите почему в issue и мы вместе подумаем над решением.
Внутри Yii 2 собственный контейнер не используется, а все компоненты лежат в Yii::$app, прямо как в первой версии.
Используется. Поэтому возможно, например, вот это: http://www.yiiframework.com/doc-2.0/guide-concept-di-container.html#practical-usage
Вот автовайринга в ядре нет. Потому что во-первых — рефлексия, а во-вторых — при чрезмерном использовании отладка лазанья-кода с ним действительно превращается в ад.
Active Record
Единственный минус вытекает из сильной связанности фреймворка — если ваша бизнес-логика оказалась в AR-моделях, то переиспользовать все это добро можно только в рамках проектов на Yii.
Хотели переиспользовать — нечего было бизнес-логику завязывать на работу с базой… если её запихать, например, в entity из Doctrine, которые вроде отдельные, а вроде и с метаданными в виде тучи аннотаций — лучше не будет. Хотите чистого кода — выделяйте его в отдельный слой. Да, это не просто, но одинаково не просто при использовании чего угодно потому как от фреймворка не зависит.
Фронтенд
Для установки Yii 2 вам нужно в принудительном порядке поставить глобально fxp/composer-asset-plugin, для того, чтобы поставить jQuery c помощью composer-а, для того, чтобы установился Yii.
Со следующего релиза 2.0 уже нет. И долго ждать тоже не нужно. Хотя да, использовать fxp было рисковым предприятием и косяков вылезло много.
jQuery входит в обязательные зависимости Yii 2.
Пока да.
Если знаете, как поставить Yii без возни с ненужными фронтенд-пакетами — пишите в комментариях.
https://github.com/cebe/assetfree-yii2
Все остальные компоненты
Абстракция над HTTP, кеширование, логирование… они есть, и они без проблем выполняют свои задачи.
Конечно же они самобытные, гвоздями прибитые к Yii, и не имплементируют соответствующие им PSR-ы.Уже писал в комментах, но повторю. Во первых, это не совсем так: https://github.com/yiisoft/yii2/wiki/PSR-adoption
Во-вторых, некоторые PSR ещё не были приняты на момент релиза 2.0 и ломать обратную совместимость сразу после их принятия было ни к чему.
Будущее Yii
Код, написанный на PHP, работает везде, а код, написанный на Yii — только на Yii. Вы либо ставите на Yii всё, либо ничего. Это риск для долгосрочного проекта.
В чём именно риск, поясните.
Конечно, приложив усилия, можно писать framework-agnostic код и разруливать все через DI-контейнер, но это не поощряется.
Если вы все-таки решитесь на это, вам прийдется забыть про Yii-вский ActiveRecord или начать писать неприлично толстые прослойки между фреймворком и вашей бизнес-логикой.
Но это, мягко говоря, неоправданно.Не понял, при чём там ссылка на issue, созданный членом команды Yii, где нет ни слова про DI.
И ещё не понял, почему это я не могу взять, например, независимый Facebook SDK и использовать прекрасно в Yii, внедрив его в конструктор сервиса через autowiring?
Если вы наследуете какой-либо класс своего приложения от любого другого класса Yii, без Yii вы его работать не заставите, ведь он обязательно наследует Object или Component. Вот.
Даже если вы вытащите вместе с ним весь ворох родительских классов и реализуемых интерфейсов, это вам не поможет.Аргументы из серии "а вдруг мне после трёх лет разработки проекта нужно будет поменять фреймворк" — они про коней и вакуум. Такого быть не должно. Если такое есть, в проекте что-то фатально не так.
С модными нынче DDD и CQRS/Event Sourcing Yii также вам не помощник. Скорее, даже будет вставлять палки в колеса.
С DDD tactical вам мало что из современных фреймворков поможет. Палки Yii в колёса не вставляет, если вы знаете, как готовить DDD.
Команда фреймворка всё пишет сама. Даже VarDumper они написали свой, а не взяли из компонентов Symfony.
Потому что компонентов Symfony тогда ещё не было. Отказаться от всего, что мы написали просто потому, что есть альтенатива у другого фреймворка — не лучшая идея, особенно если наш код не хуже и поддерживать его не составляет проблем.
Регулярно поддерживать и улучшать столько компонентов — очень непростая задача для небольшой команды. И у этой команды есть два пути.
Во первых, можно оставить все как сейчас.
Все компоненты пишем сами. Сильная связанность. Полностью изолированная экосистема фреймворка. Небольшое уютное комьюнити. Медленная деградация.
Во-вторых, можно все-таки разбить монолитный Yii на независимые от фреймворка компоненты.
Но тогда это будет уже не Yii с простым и удобным API, а просто еще один набор компонентов, не востребованный вне экосистемы Yii.
Оба пути ведут в никуда.Вот только пути не два и не обязательно пускаться в крайности. Например, можно пойти по пути Laravel — выкинуть всё своё, взять за базу компоненты Symfony, написать к ним обёртки и допы. Часть кода можно выделить в библиотеки. Тот же слой i18n у Yii один из самых мощных, так что за востребованность можно не беспокоиться. Или можно часть кода выделить в расширения и подключить к их поддержке и разработке заинтересованных людей. Это уже сделано с ElasticSearch, Docker и очередями и такой подход показывает себя неплохо.
PHP 7
Но если мы хотим использовать тайпхинтинг, все это удобное API превращается в тыкву.
У вас опять крайности. Тайпхинтинг нужен не для того, чтобы его использовать, а для того, чтобы поймать ошибки. В вашем приложении никто не запрещает им пользоваться, а именно там случается большинство ошибок. Сам фреймворк хорошо оттестирован.
Qiang так и не вернулся
Самые внимательные заметили отсутствие через пять месяцев. Это означает только одно — даже если "грузовик передет" ещё одного члена core team, фреймворк не умрёт.
symbix
16.07.2017 22:13Хотели переиспользовать — нечего было бизнес-логику завязывать на работу с базой
На самом деле, можно не завязываться на базу даже используя ActiveRecord, если реализация ActiveRecord такое позволяет.
Всю работу с базой можно вынести в репозитории и сделать вид, что AR-методов больше нигде нет. Какая разница, $fooMapper->find($id) или FooModel::find($id)? А конфигурацию AR можно рассматривать ровно как доктриновские аннотации и не считать частью модели.
Наверное, можно даже сделать прослойку вида
class Entity extends yii\ActiveRecord {}
и вынести AR-конфигурацию из моделей в трейты :)
entity из Doctrine, которые вроде отдельные, а вроде и с метаданными в виде тучи аннотаций
Doctrine позволяет вынести маппинг в отдельные файлы. Аннотации опциональны. Мне они тоже не нравятся.
pbatanov
16.07.2017 22:16А можно использовать в качестве модели сторонний класс, который не унаследован от иерархии актив-рекорд? Доктрина такое позволяет.
SamDark
16.07.2017 22:19Нет, в Active Record нельзя. Сам паттерн создан для обратного. Доктрина — не Active Record.
pbatanov
16.07.2017 22:22Ну я это написал к тому, что не завязывать модели на актив-рекорд не получится. Кстати доктрина позволяет организовать ActiveRecord-like работу
Fesor
16.07.2017 22:33Вот только лучше так не делать. Никогда. Лучше подключите к проекту любую популярную реализацию active record если вам так надо, в этом ничего плохого нет. А вот калечить доктрину и использовать ее внутренние механизмы в вашем коде — дело плохое.
pbatanov
16.07.2017 22:39В смысле внутренние и почему калечить? Это «изкоробочное» решение, на основе которого можно сделать свои методы активных моделей через какой-нибудь трейт
Но самому пользоваться еще не доводилось.Fesor
16.07.2017 23:54В смысле внутренние и почему калечить?
В том смысле что эта штука юзается по сути исключительно для прокси-классов. Это не часть публичного API.
Те же prePersist/postPersist тоже не рекомендуется юзать.
pbatanov
17.07.2017 09:42Либо я что-то не понимаю сам, либо не понимаю вас. В прокси классах юзается отдельная фабрика, в которую отдельно передаются EM и метаданные
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Proxy/ProxyFactory.php#L124
Эти две штуки вроде особо не связаны и в комментах к интерфейсу прямо написано, что он используется для построения
to implement ActiveRecord functionality on top of the persistence-ignorance that Doctrine propagates
https://github.com/doctrine/common/blob/2.4/lib/Doctrine/Common/Persistence/ObjectManagerAware.php#L29
SamDark
16.07.2017 22:37Почему не получается? Делайте Model и Repository. Кто мешает?
pbatanov
16.07.2017 22:46Я правильно понимаю, что берется сторонний класс, для него делается репозитрий, который наследуется от AR? Но в таком случае разве репозиторий не будет возвращать инстансы самого репозитория вместо модели? или надо будет писать кастомную инстанциацию объектов?
SamDark
16.07.2017 22:49Нет. Ничего не наследуется от AR. Используется либо AR внутри репозитория, либо вообще не используется. Query Builder тоже неплох.
SamDark
16.07.2017 22:49Инстанциацию кастомную надо, да. Что-то вроде https://github.com/samdark/hydrator
symbix
17.07.2017 01:36Довольно бессмысленный перегон данных туда-сюда получается.
Я особо не знаком с yii, но я не вижу существенных проблем в подходе типа:
abstract class Entity extends \yii\ActiveRecord {} class Foo extends Entity { use FooRecord; // here goes all the yii AR code public function myDomainMethod() { ... } }
Единственное, что сразу приходит в голову — наверное, с конструктором будут проблемы.
Fesor
16.07.2017 22:35Сам паттерн создан для обратного.
ну формально этот паттерн создавался для упрощения работы с данными в data-centric приложениях, где даже row data gateway уже оверкил. Но про необходимость наследования никто на самом деле не говорит. Можно например прокси-классы юзать и вуаля. Другое дело что ProxyManager помоложе вашей реализации AR.
Хотя я хз, как по мне реально на сегодняшний день для вещей где active record нельзя проще через cqrs фигачить, и использовать AR для read model. Хотя для дата мэпперов место еще есть.
symbix
17.07.2017 01:43Мне кажется, что у rails-подобных AR в качестве read model как раз проблемы.
Read model — они же такие, зависят от контекста. Скажем, чтобы далеко за примером не ходить, есть хабрапосты, и мне временами надо для них выбрать количество комментариев, а если пользователь авторизован — еще и количество новых. Куда их, пардон, засунуть? В динамические атрибуты, и потом каждый раз гадать, есть ли там что?
zelenin
17.07.2017 02:40+3даже если "грузовик передет" ещё одного члена core team, фреймворк не умрёт.
это только если считать фреймворк живым. После ухода Qiang (а уже прошло время и можно сделать вывод), считавшего фреймворк своим детищем и непосредственно вкладывавшегося в его развитие, продукт стал двигаться в сторону умирающих фреймворков типа codeigniter и cake с некоей своей тусовкой сектантов и вяловатой core-team. Спустя шесть лет после начала разработки, трех лет после релиза и практически моментального морального устаревания только началось обсуждения новой версии. Раньше 2018го ожидать ничего не приходится. И то если это будет патч-релиз, ломающий совместимость в нескольких компонентах. 4 года на одной версии, превращающейся в то, чем стала yii1 на 2013-4 год. 4 года это гигантский срок.
Ну а сделать кардинально новый релиз как был yii2 по отношению к yii1 современная команда разработки просто не осилит. Боюсь даже грамотно раздербанить монолит на компоненты будет трудной задачей, и это мы не увидим раньше 2019го (если вообще увидим).SamDark
17.07.2017 11:08+14 года — это время жизни нормального проекта. Не каждые же пол года ломать всё и релизить мажорную версию...
pbatanov
17.07.2017 11:21+1Релизный цикл симфони — 2 года, перед выпуском нового мажора выпускают лтс для предыдущей версии. при этом этот LTS находится в «пограничном» состоянии, т.е. в нем обычно работает старый функционал, но кидается депрекейтами и уже работает новый функционал. в x.0 депрекейты выпиливают.
Т.е. «ломать все» как раз таки необязательно, без проблем пишутся библиотеки, которые поддерживают "~2.7 || ~3.0", а потом, думаю и "~2.7 || ~3.0 || ~4.0".
php_freelancer
17.07.2017 03:12+3Отстутсвующие фичи из других фреймворков либо настолько редко используются, что никому не нужны, либо просто их никто не просил. Так мы не против допила контейнера, если в этом есть необходимость. Если вам лично нужна какая-то фича, опишите почему в issue и мы вместе подумаем над решением.
Так в этом и проблема — Yii сообщество не знает, что им нужен нормальный DI, во всех примерах и уроках по Yii ни намека на контейнеры. В основном Yii::$app — это весь DI и в этом и есть весь выстрел в ногу, особенно, когда оно используется за пределами контроллера или команды.
Когда класс компонента юзает Yii::$app, он начинает мочь всё и вся, он перестает быть прозрачным и любой потенциальный юнит тест на него скорее всего бесполезен, ибо, например, замокать зависимость класса, которая юзается в компоненте через Yii::$app — не, ну никак.
Но сколько не спрашиваю, мало кто из Yii разработчиков этим обеспокоен и 99% просто не знают о mock\stub.
Данный фреймворк дает возможность делать всякую бяку из коробки, у него самый ужасающе низкий порог вхождения. И поэтому подавляющее большинство разработчиков максимально неопытны и формируют вредные взгляды о PHP cообществе в целом.SamDark
17.07.2017 11:13+2Порог действительно низкий. Это так.
Вы хотите, чтобы на PHP были либо опытные продвинутые разработчики, либо никого? Я нет потому что тогда сильным проектам, где эти продвинутые разработчики нужны, будет неоткуда вырастать.
Yii допускает много вольностей. На нём можно быстро фигачить, а можно писать грамотно и хорошо. Зависит от опыта и дисциплины того, кто пишет.
pbatanov
16.07.2017 21:59Меня лично всего меня вымораживает то, что все встроенные валидаторы требуют, чтобы проперти были не ниже, чем protected, иначе ни публичного доступа нет, ни встроенные __get __set до них не доберутся
SamDark
16.07.2017 22:04Поясните, как вы хотите получить публичный доступ к private?
pbatanov
16.07.2017 22:14Идеальный ответ — никак. Я бы хотел наложить валидатор на метод в таком случае.
Если простым путем — через рефлексию
Если универсально, то вот https://symfony.com/doc/current/components/property_access.html, штука сама выберает, как обратиться к свойству, через метод, магию или публичный доступSamDark
16.07.2017 22:21В Yii вы можете навесить валидатор на соответствующий приватному свойству геттер. А вообще валидировать приватные свойства не в конструкторе и не в сеттере несколько странно.
pbatanov
16.07.2017 22:24А можно пример? Это какие то отдельные валидаторы? или работает через магический геттер? Потому что в коде по ссылке выше идет прямое обращение к атрибуту
SamDark
16.07.2017 22:38Через магический геттер.
pbatanov
16.07.2017 22:43ну, магический — это не совсем «соответствующий приватному свойству». Например, если оперировать терминами той же доктрины, то в свойствах связей toMany лежит обычно Collection, а геттер отдает массив для того, чтобы нельзя было эту коллекцию мутировать.
ясно, спасибо
rsvasilyev
16.07.2017 22:15А вот и нет: https://habrahabr.ru/post/178917/
Да, насчет сроков могу ошибаться
PSR-4 совместимом autoloader-е, необходимом для поддержики алиасов
Что плохого в системе алиасов для путей файловой системыТо, что для ее поддержки пришлось писать свой автолоадер?
В итоге теперь мы оперируем и неймспейсами и алиасами. Алиасы для ФС выглядят как вынужденное наследие Yii 1, а не фича.
В чём именно риск, поясните.
Аргументы из серии "а вдруг мне после трёх лет разработки проекта нужно будет поменять фреймворк" — они про коней и вакуумРечь конечно идет не о проектах.
Например, мы работаем в компании, где пишутся продукты с более-менее похожей кодовой базой. Функционал можно и нужно переиспользовать.
Выделяя модули/расширения Yii-шного приложения в отдельные пакеты, мы на много лет вперед привязываемся к текущей мажорной версии Yii. Либо вынуждены писать максимально абстрагируясь то Yii, что очень непросто.
Например, можно пойти по пути Laravel
Будет интересно услышать от вас планы по развитию фреймворка.
даже если "грузовик передет" ещё одного члена core team, фреймворк не умрёт
Это здорово и правильно. Просто странно, что Qiang ушел так незаметно. Если не секрет, кто сейчас решает стратегические вопросы?
SamDark
16.07.2017 22:31+2То, что для ее поддержки пришлось писать свой автолоадер?
Нас, кроме алиасов, интересовала ещё и скорость загрузки классов. На момент релиза Yii лодер Composer-а был совсем плох в этом плане. issue на тему loader-а практически не было, работает всё стабильно, каши не просит.
В итоге теперь мы оперируем и неймспейсами и алиасами. Алиасы для ФС выглядят как вынужденное наследие Yii 1, а не фича.
Алиасами мы для загрузки классов не оперируем. Как и не оперируем неймспейсами для работы с файловой системой.
Выделяя модули/расширения Yii-шного приложения в отдельные пакеты, мы на много лет вперед привязываемся к текущей мажорной версии Yii. Либо вынуждены писать максимально абстрагируясь то Yii, что очень непросто.
Так этот факт не меняется вне зависимости от используемого фреймворка. Писать независимые компоненты сложнее, чем завязанные на другой код.
Будет интересно услышать от вас планы по развитию фреймворка.
Эволюционные. Будем облегчать ядро, избавляться от всяких jQuery, выкидывать версии PHP до 7-ки, выкидывать HHVM. Выпиливать части в расширения и независимые библиотеки, которые, по возможности, будут поддерживаться заинтересованными разработчиками. Облегчать дерево наследования и стремиться выпилить его совсем...
Революции вроде 1.1 > 2.0 не хочется. По крайней мере пока.
Если не секрет, кто сейчас решает стратегические вопросы?
Я, Carsten Brandt, Дмитрий Науменко, Климов Павел, Boudewijn Vahrmeijer.
pbatanov
16.07.2017 22:35+1Так этот факт не меняется вне зависимости от используемого фреймворка. Писать независимые компоненты сложнее, чем завязанные на другой код.
Вот это совсем неправда. Вам говорят о том, что сложно писать модули в Yii, не привязанные к Yii. А не вообще к любому коду.
В симфони очень легко пишется независимая библиотека, к которой рядом (сверху) кладется бандл, семантическая конфигурация и расширение для DI. За примерами далеко ходить не надо — JmsSerializer + JmsSerializerBundle, DoctrineOrm + DoctrineBundle и тд. Делается очень просто все.SamDark
16.07.2017 22:42+1Так и в Yii можно так же. DI контейнер в фреймворке вполне себе универсальный и может настраивать не только классы самого фреймворка.
Также посмотрите на обилие прослоек, коннекторов и обёрток для независимых библиотек, реализованных в виде extension-пакетов.
pbatanov
16.07.2017 22:49Ну насколько я понимаю, суть претензии выше в том, что для того, чтобы интегрировать внешний код в Yii, приходится как раз таки эти обертки, прослойки и коннекторы реализовывать, просто чтобы подключить библиотеку. В симфони в принципе достаточно только описать класс для DI, а с версии 3.3 уже иногда и это можно не делать (для простых случаев).
SamDark
16.07.2017 22:54Да не, не приходится. Отлично всё конфигурируется либо через контейнер, либо по месту. Просто люди привыкли делать обёртки ещё с 1.1 и по инерции наделали их очень много...
rsvasilyev
16.07.2017 22:42Спасибо.
Будем облегчать ядро, избавляться от всяких jQuery, выкидывать версии PHP до 7-ки, выкидывать HHVM. Выпиливать части в расширения и независимые библиотеки, которые, по возможности, будут поддерживаться заинтересованными разработчиками. Облегчать дерево наследования и стремиться выпилить его совсем…
Революции вроде 1.1 > 2.0 не хочется. По крайней мере пока.Если честно, звучит как переход в стадию поддержки.
rsvasilyev
16.07.2017 22:42Извините, промазал.
Это был ответ к https://habrahabr.ru/post/333398/#comment_10314816
SamDark
16.07.2017 22:48Я много чего не озвучил: https://github.com/yiisoft/yii2/wiki/Plan-for-next-major-versions Плюс посмотрите issue на 2.1.
malinichev
16.07.2017 22:36+3Могу написать только одно.
Yii2 ускоряет и упрощает разработку, но, гавнокода становится больше!
Например на том же Phalcon, Laravel и т.д. разработка может идти немного дольше, но компонентность будет сохранена в нормальном виде, и не будет привязки к фреймворку.
Я за Phalcon and Laravel в долгосрочных и сложных проектах, и Yii2 для срочной разработки и возможно в будущем сложных проектах(с обязательным переносом на новый фреймворк через 2-3 года)SamDark
16.07.2017 22:51+4с обязательным переносом на новый фреймворк через 2-3 года
А сразу писать нормально или порефакторить потом никак?
malenkiy_rak
17.07.2017 10:43+2Например на том же Phalcon, Laravel и т.д. разработка может идти немного дольше, но компонентность будет сохранена в нормальном виде, и не будет привязки к фреймворку.
Да ладно… "компонентность". В Laravel есть десяток способов провалидировать данные с формы, и каждый из них похож на говнокод. Как тут можно удержаться от
и не будет привязки к фреймворку
Тогда нафига вам фреймворк? Берёте composer, ставите десяток либ и фигачите уникальное сочетание (месиво) компонентов, которое будут изучать каждый новый разраб, пришедший на проект. Уж лучше монолитный фреймворк со всем необходимым функционалом, чем кучу модулей, как в symfony.
Ах да. Напомню, что wordpress уязвим из-за сторонних плагинов. Так кто мешает делать дырявые модули для всех фреймворков, пускай и рабочие модули?
Я за Phalcon and Laravel в долгосрочных и сложных проектах, и Yii2 для срочной разработки и возможно в будущем сложных проектах(с обязательным переносом на новый фреймворк через 2-3 года)
Какой-то не очень долгосрочный проект, если уже через 3 года на новый фреймворк нужно переносить.
Я за Phalcon and Laravel
Что-то не слышал, чтобы Phalcon развивался быстрее Yii.
Samouvazhektra
17.07.2017 00:08+8Наверное заминусуют, но…
Yii, вероятно, самый популярный PHP фреймворк на просторах СНГ.
Многие годы он был замечательным инструментом и помогал нам зарабатывать на хлеб с маслом.
А что вы для него сделали?
За symfony и laravel в том или ином виде стоит коммерция, облака, поддержка, сервисы, всякие и проч.
yii2 развивается за счет комьюнити и энтузиазма разработчиков и только за это им огромный респект, потому что на хлеб с маслом они помогают заработать очень многим.php_freelancer
17.07.2017 03:15+2Разве не правильнее было бы юзать продукт, у которого уже сейчас имеются LTS релизы, ком. поддержка и прочее в проекте, который планирует достаточно долго развиваться?
Что мы сделали для Yii, чтобы он стал лучше? А зачем, когда уже сейчас есть Симфони, который во всю финансируют?
Тем временем в Yii как известно, один из основных разработчиков ушел в Go.
Зачем тратить деньги на доработку Yii, если можно взять Симфони прямо сейчас и быть уверенным в завтрашнем дне и в выходе Symfony 4 Flex в ноябре?malenkiy_rak
17.07.2017 10:52-2Разве не правильнее было бы юзать продукт, у которого уже сейчас имеются LTS релизы, ком. поддержка и прочее в проекте, который планирует достаточно долго развиваться?
Angular видел? Каждая версия хрень какая-то. Зато LTS!!!
Зачем вам LTS? Вон nodejs 0.12 сколько лет существовал и на нём кучу проектов запилили, и ничего не произошло. Находите баг, пишите issue и всё ок и без всяких LTS. К тому же кто вам мешает сделать исправления самостоятельно? Дебажить не умеем что ли?
Зачем тратить деньги на доработку Yii, если можно взять Симфони прямо сейчас и быть уверенным в завтрашнем дне и в выходе Symfony 4 Flex в ноябре?
И что вам это даст? Те же возможности писать говнокод, как и везде, те же баги, уязвимости, велосипеды. Ах да!!! Цифра 4 небось привлекает? Тут вспоминается Windows Vista, 7, 8, 8.1, 10. У них то финансирование побольше будет, чем у symfony, а толку 0.
Пишите на том, что вам нравиться, а не что финансируется. Как по мне и codeigniter вполне нормальный для разработки, если голова на плечах есть. Ничто не мешает сделать на нём сложный проект с любой архитектурой, было бы желание его в достаточной мере изучить.php_freelancer
17.07.2017 18:36+2Ой, сколько восклицательных знаков.
Пишите на том, что вам нравиться, а не что финансируется. Как по мне и codeigniter вполне нормальный для разработки, если голова на плечах есть. Ничто не мешает сделать на нём сложный проект с любой архитектурой, было бы желание его в достаточной мере изучить.
Ну если безответственно подходить к вопросу выбора стека технологий, например, для домашнего проекта, то все ок.
А так сразу вспоминается любимая Коханочка, которая резко и неожиданно прикрылась к чертям собачьим. Вот это была жопка, мало того, что все сразу начали усилинно линять с фреймворка, так еще через какое-то время х*як — https://habrahabr.ru/post/150201/
И это не нормальное состояние проекта, за который тебе платят деньги.
И про Symfony Flex советую побольше почитать, много интересного на самом деле планируется, симфони практически стало единственным в мире PHP, что достойно внимания.
Чисто из интереса, даже и про недавний 3.3 релиз можно почитать, ибо много добавлено плюшек с DI.
Т.е. ребята реально работают и делают нашу работу удобнее.
P.S:
http://school-assistant.ru/?predmet=russian&theme=pravopisanie_tsia_v_glagolax
egoserg
18.07.2017 10:20-1О да.
Вот только в Symfony и laravel напихали всего в базовую сборку.
А вот нужных компонентов которые используются в 99% нет.
Даже взять к примеру grid
я смотрю на эти гриды Symfony и laravel и мне хочется блеватьfranzose
18.07.2017 11:16Есть SyliusResourceBundle
egoserg
18.07.2017 11:40Ну если вам кажется, что это отличное решение.
И этим удобно пользоваться.
Пользуйтесь на здоровья.
Но мне вас жалкоfranzose
18.07.2017 11:47А что с этим решением не так?
egoserg
18.07.2017 11:56http://docs.sylius.org/en/latest/bundles/SyliusGridBundle/your_first_grid.html
Оооо да.
Это вообщу юзабельно.
А казалось простая задача, сделать грид.
egoserg
18.07.2017 12:02Я конечно могу ошибаться.
Но к примеру laravel содержит в комплекте систему для реализации очередей.
Я не уверен что этот функционал юзают все проекты.
А вот теже гриды юзаются во всех проектах.
И где тогда логика?franzose
18.07.2017 13:25Очереди — весьма полезная вещь. Если вы, конечно, не хотите заставить пользователя ждать всё то время, пока отправляется почта или генерится какой-то файл, отчёт и т.п.
symbix
18.07.2017 13:53+1А вот теже гриды юзаются во всех проектах.
Такой ваш опыт говорит только о том, над какими проектами вы работаете. Мир богаче, поверьте.
Я никакие гриды (и вообще серверные UI-компоненты) не использовал уже лет 8 (этим занимается фронтенд-фреймворк типа Angular/React/Vue), а вот очереди мне нужны практически в каждом проекте.
egoserg
18.07.2017 14:31Вы хотите сказать, что у вас проекты без админ части и у вас нет там гридов?
>>> нужны практически в каждом проекте
Даже сами ответили. Что почти.
Это означает что не на всех проектах.symbix
18.07.2017 14:40Это означает что не на всех проектах.
Да, бывает, когда простенькое rest api надо и больше ничего — беру Lumen.
Вы хотите сказать, что у вас проекты без админ части и у вас нет там гридов?
Бывает и совсем без (управляется все cli-командами). Бывает, что есть некоторый UI администратора, пишется на том же Angular/React. Того, что вы называете "гридами" — нет.
VolCh
19.07.2017 04:38+2Сейчас во многих проектах на PHP вообще может не быть веб-морды — SOA, микросервисы и всё такое. Веб-морды отдельные проекты на всяких JS-фреймворках, в том числе автоматически сгенерированные на базе документации к API. А если есть, то гриды на них совсем не обязательны.
egoserg
19.07.2017 10:41Я с вами частично согласен.
Но тут получается такой момент, что изза прихоти разработчика клиент платит больше. А в замен особо важного ничего не получает.
Простой пример.
Задача в админке отображать грид для инвойсов.
Задача довольно тривиальная и ее можно сделать очень быстро.
Но вы предлагаете поставить ангуляр или реакт и тд. тп.
Написать мега конфик для роутинга, написать API для этого, + реализовать грид на фронте или найти нужный пакет затянуть и настроить его.
И что получается.
В место того, чтобы эту задачу сделать за 1 час (Грид, редактирование, удаление, просмотр)
Сколько уйдет времени у вас?symbix
19.07.2017 11:05+2Разделение труда. Фронтедом занимается фронтенд-разработчик, бэкендом-бэкенд-разработчик. Каждый делает то, что он хорошо умеет.
Ну и не весь веб — это сайты компаний и интернет-магазины. Функциональные требования к системе администрирования бывают очень разные.
franzose
19.07.2017 11:11+1Вот такие вот решения «по-быстрому» приводят в конечном итоге к печальке и аду касаемо поддержки и разработки новых функций.
michael_vostrikov
19.07.2017 11:20+1Это не «по-быстрому», это нормальное использование средств фреймворка для серверного рендеринга HTML.
franzose
19.07.2017 11:24Я не имею ничего против GridView как такового. Я прицепился к фразе «за час». Надобность «вчера» частенько предрекает разработку в стиле «херак-херак» и в продакшн...
michael_vostrikov
19.07.2017 11:33+1Так с GridView описанная задача и решается за час) Потом никаких доработок не требуется.
jetexe
19.07.2017 11:34+1ну вывод грида из таблички с реляциями делается даже меньше чем за час (с родным компонентом).
VolCh
19.07.2017 13:08Предполагается, что сервис инвойсов уже есть и работает. Его API не просто документировано, а документация в машиночитаемых стандартах, позволяющих запускать всякие генераторы фронтендов. Вплоть до генераторов админок в одном статическом файле. Ну, пускай в трёх: css, js и "болванка" HTML.
Fesor
19.07.2017 13:31+1Сколько уйдет времени у вас?
1 час.
4 месяца назад мне надо было по быстрому наваять простенький грид где люди могли бы фильтровать данные, много данных, по данными миграции пользователей с одного сервиса на другой.
- SQL запрос для API — 10 минут.
- закрыть API http basic авторизацией — 5 минут
- сделать
ng new migration-report
— 5 минут — можно сходить за кофе - подключить какой-нибудь готовый data grid, настроить и т.д. — пол часа.
- добавить деплой скрипты и потестить — 15-20 минут
r3verser
19.07.2017 16:45Это утопия, либо если задача уже была решена раньше много-много раз и решение отработано, чаще всего на 4 пункте, когда вдруг понадобиться какая-нить нужная фишечка, вдруг оказывается что… и начинается ебля со сторонними либами...;)
Fesor
19.07.2017 22:08либо если задача уже была решена раньше много-много раз и решение отработано
ну так оно и было, или вы хотите сказать что в yii люди волшебным образом обретают знания или у них не возникает вопросов "а как в этом CGridView (или как оно там называется) сделать чуть другое форматирование этой штуки"?
вдруг оказывается что…
нормальные гриды позволяют вам хоть свой компонент в ячейку запихнуть. И делайте там что хотите и как хотите. А вы пробовали что-то нестандартное делать с GridView? не знаю как во втором но в первом Yii это было то еще развлечение. И уж тем более я не скучаю по вставкам из кривого JS на jquery размазанного по массиву конфигурации в php файлах. И да, это не потому что "нельзя нормально" а просто потому что "а почему бы и нет".
michael_vostrikov
19.07.2017 18:05ng new
Ну так он уже у вас был. А если в проекте его нет, то проще на PHP+HTML сделать.
oxidmod
19.07.2017 21:04npm install -g angular-cli ng new
Это такая трабла поставить, что прямо не знаю…michael_vostrikov
19.07.2017 21:45И npm сначала надо поставить. И структуру проекта нужную сделать. И какой-нибудь готовый грид выбрать. И вообще хотя бы ангуляр выучить)
Fesor
19.07.2017 21:55И npm сначала надо поставить.
docker run -it --rm -v `pwd`:/app node npm install`
это чтобы еще больше раззадорить.
Да и потом, даже если вы делаете что-то с html и стилями уже есть немало поводов поставить node хотя бы что бы иметь возможность юзать пре/пост-процессоры стилей и прочие радости жизни.
Ибо так можно рассуждать и в духе "так это надо php поставить".
И вообще хотя бы ангуляр выучить)
И не забыть перед этим выучить javascript. То есть оно очевидно требует намного больше знаний. но дает намного больше свободы в том что и как вы собираетесь делать. И это не те вещи которые "сложно" учить — вовсе нет. Принципы базовые применимы везде, подходы схожи, если с ними у вас проблем нет — разобраться с ангуляром тем же или реактом не является проблемой или чем-то неподъемным.
Да, вы врядли будете иметь возможность тыкать любую хайповую штуку которая вышла на той неделе, но вам это и не надо — вы же работу делаете.
michael_vostrikov
19.07.2017 23:10Так суть не в том, что неподъемно, а в том, что проще за час сделать готовыми средствами, чем час потратить на изучение ангуляра и его установку ради таблицы. Тем более что в первом случае это скорее 20 минут, а во втором полдня.
Fesor
19.07.2017 23:55а в том, что проще за час сделать готовыми средствами, чем час потратить на изучение ангуляра
как насчет инвестировать месяц в изучение новых штук которые позволят вам делать не просто на коленке что-то однообразное а даст чуть больше выбора в том что и как вы делаете?
Я ушел с неповоротливых CRUD генераторов аля yii на CRUD генераторы для SPA, и получаю больше ценности от них. Вот и все. Количество работы которое требуется сейчас либо эквивалентно либо меньше, с учетом развития инструментов. А для конечного пользователя более отзывчивый интерфейс создает чуть больше вув эффекта. Может казаться мелочью, но на самом деле для выстраивания отношений с клиентом очень помогает.
В целом я не пытаюсь вас в чем-то убедить. Это моя субъективная точка зрения, любой способ делать дела которые работает сгодиться.
VolCh
20.07.2017 12:29+1А сколько надо потратить на изучение "готовых средств"? Тем более, как я понимаю, основная претензия к Yii — сильная связанность его компонентов, вещь в себе. Изучив же даже азы современной фронтенд-разработки, вы сможете делать админки даже к бэкендам, написанным на неизвестном вам языке.
LastDragon
20.07.2017 13:14Так они наверняка уже освоены, а если разбираться в angular-e то нужен не столько js, сколько ts + тут можно найти кучку магических несовместимостей при сборке… Что весьма попортит нервы :) (поэтому тупо ставим angular-cli, этого совета кстати весьма не хватает в доке...)
VolCh
20.07.2017 14:02-1Не наверняка. Вот приду я на проект, где Yii. Cкажут мне сделать админку.
У меня два варианта: сделать админку на, например, React, которая возможно не то, что Yii, а даже PHP на проекте переживёт. Или начинать изучать как делать админки на Yii с убеждением, что для чего-то сложного нужно будет или бороться с Yii, или выкидывать то, что сделаю после изучения. Какой вариант разумнее в общем и в целом?
LastDragon
20.07.2017 15:15От проекта зависит — если всё остальное уже на yii, то выбора как бы и нет (или должны быть очень веские причины чтобы внедрить что-то незнакомое).
r3verser
20.07.2017 15:36+1React классная штука, с Yii гридами и в сравнение не идет конечно, проблема в инфраструктуре, он тянет за собой nodejs, npm, webpack/brunchjs, jsx, babel, jslint/eslint, тесты!!! и еще кучу всего, помню как у меня голова кипела первую неделю от этого всего, ахаха)) То-есть по сути реакт разработчик это отдельная профессия, а так да, крутая штука.
r3verser
20.07.2017 15:40+1и еще новичкам хочу посоветовать вместо wepback вначале юзать brunchjs, когда упретесь перейдете на webpack, если упретесь, ибо webpack я ненавидел больше всего когда начинал с работать с реактом.))
Fesor
21.07.2017 10:20я бы новичкам рекомендовал вообще не заниматься конфигурацией этого всего и взять готовый стартер.
michael_vostrikov
20.07.2017 22:45+1С PHP-фреймворком PHP-разработчик работает чаще, чем с JS-фремворками для SPA. Поэтому речь не идет о том, чтобы изучить Yii для того чтобы сделать грид. А вот с ангуляром, если его не планировалось добавлять в проект заранее, речь идет именно об этом.
symbix
20.07.2017 14:52Мужик пилит ножовкой дерево, мимо проходит другой
– мужик, ты чо, есть же бензопила, с ней быстрее!
– я не умею
– там научиться — час времени
– мне некогда, мне лес валить надо!Если действительно ради простой таблицы, то, конечно, не стоит того. Но вот владеть инструментом, чтобы в случае, когда он будет более эффективен, им воспользоваться — стоит.
michael_vostrikov
20.07.2017 23:00+2Вот как раз научиться правильно использовать ангуляр, а не "тяп-ляп по-быстрому", надо гораздо больше часа. А с GridView задача решается за 20 минут, включая связи между сущностями, форматирование, интернационализацию, пагинацию, сортировку, проверку прав доступа на действия, без лишнего выставления наружу API для этих данных специально для грида.
symbix
20.07.2017 23:22А другие задачи на angular решаются за 20 минут, а серверными yii-компонентами не решаются вообще.
michael_vostrikov
20.07.2017 23:37Так а может других задач и не надо решать) Я ж не говорю, что ангуляр это плохо, просто в некоторых задачах он добавит лишнее время и сложность.
Fesor
21.07.2017 10:23надо гораздо больше часа.
Конечно, как бы что бы выучить PHP и величать себя бэкэнд разработчиком нужно даже больше времени скажу я вам.
michael_vostrikov
21.07.2017 10:35Ну вот я говорю о ситуации, когда знание PHP уже есть, бэкенд-фреймворк есть, а знания фронтенд-фреймворков нет, и даже цели нет внедрить их в проект, потому что никакого профита это не принесет.
VolCh
21.07.2017 14:05Это через API или при условии использования исключительно родной ORM?
michael_vostrikov
21.07.2017 15:10ActiveDataProvider + GridView + компоненты, которые они используют. Можно написать DataProvider для другой ORM.
SpbSprut
17.07.2017 01:14Надо мне тоже умных книжек почитать, а то пишу на yii, yii2 и не парюсь особо)) а вот прочитаю парочку и пойму что все не правильно делал…
Идеального фреймворка не бывает как и идеального кода. Любое принятое решение или выбранный фреймворк в текущий момент, могут в будущем оказаться как удачным решением так и нет в зависимости от того какой новый функционал необходимо будет в него внести (что заранее знать невозможно). Даже если вы будете писать все с нуля, то через несколько лет вас начнет не устраивать свой собственный код и его надо будет переписывать или писать все с нуля.VolCh
17.07.2017 06:20+1Но всё же у одних решений больше вероятности не вызывать боли в будущем, а у других меньше. Ну и цена изменения решения.
DeLuxis
17.07.2017 07:00+1Обожаю конструктивную критику! Спасибо.
П.С. Фанат Yii, коим и буду оставаться.
Electrohedgehog
17.07.2017 08:08+4Ещё одна бессмысленная статья. Автор явно хорошо разбирается в предмете, но тексту это никак не помогло.
Да, у Yii, очевидно, есть недостатки, и привели их здесь вы далеко не полный список. И?.. Делать-то с этим что? Пригласить SamDark в запой?
Имеется достаточно удобный фреймворк с низким порогом вхождения и приемлимым уровнем сложности стрельбы в ногу. Явных, фатальных и необратимых, недостатков у него нет. Никаких разумных причин не использовать его я не вижу, те же что приводите вы тянут максимум на отказ по эстетическим соображениям.
Объясните, например, что вам кажется неправильным в структуре наследования классов? Что именно в ней говорит вам о том, что Yii теперь надо выбросить? Считаете что https://github.com/laravel/framework/blob/5.4/src/Illuminate/Database/Eloquent/Model.php более понятно? И, кстати, там реализуется шесть интерфейсов )
В общем критика-то относительно конструктивна, но никак не объясняет почему с фреймворка надо уходить. Хотите благородно негодовать на логику и качество кода — пообмазывайтесь Drupal и Bitrix, вот уж воистину где мировое зло.
Хотите пропагандировать технологии сравнением — пожалуйста. А в текущем виде статья практически ни о чём. Чем плох Yii и без вас знали.modestguy
17.07.2017 09:44+1Добавлю от себя. Конечная цель разработки: создание качественного программного продукта для конечного потребителя. Если этот продукт удовлетворяет всем требованиям, предъявляемым к его дальнейшему функционированию, совпровождению и развитию — то, КАК этот продукт реализован — с точки зрения конечного пользователя или бизнеса — неинтересно. На 2-ом курсе ВУЗа мой сокурсник написал фото-сайт, который вошёл в ТОП-3 и удерживает свои позиции высокие, посвящённые художественной фотографии. Под капотом: Delphi (да-да, web-проект на delphi) + firebird.
В умелых руках… как говорится и хрен балалайка. Поэтому, давайте пореспектуем команде Yii, за то, что они сделали… сделали то, что позволило создавать приятные продукты. То, что фрэймворк «не идеален» не гарантирует, что конечный программист не должен его использовать. Гораздо важнее учитывать все плюсы/минусы каких-либо инструментариев разработки и уметь выбирать тот инструмент, который позволит с минимальными трудо-затратами сделать качественный продукт.
И ещё: «Не ошибается только тот, что ничего не делает».
rsvasilyev
17.07.2017 09:48+1Да, у Yii, очевидно, есть недостатки, и привели их здесь вы далеко не полный список. И?
Круто, если вы уже были знакомы со всеми ими. Для кого-то один из них может стать решающим при выборе фреймворка.
Объясните, например, что вам кажется неправильным в структуре наследования классов?
Наследование уместно тогда, когда дочерний класс "есть" родительским. Квадрат и ГеометрическаяФигура. Контроллер и базовый контроллер. Но ActiveRecord и yii\web\JsExpression никак не могут иметь один и тот же родительский класс.
И, кстати, там реализуется шесть интерфейсов )
В общем критика-то относительно конструктивна, но никак не объясняет почему с фреймворка надо уходить.
У меня не было цели доказать, что с него надо уходить.
Хотите пропагандировать технологии сравнением — пожалуйста.
Статей "Yii vs X" достаточно. Статей вида "Yii — хорош" — тоже.
Electrohedgehog
17.07.2017 11:22Круто, если вы уже были знакомы со всеми ими
Не был. Просто эти недостатки за последние два года никак мне не мешали в работе. И выдвигать их как аргумент в пользу отказа от Yii я считаю некоторым преувеличением.
К наследованию вы придираетесь, как мне кажется, зря. Это просто попытка реализовать средствами языка то, что в нём не заложено. Если бы вам пришлось писать PHP на PHP то и Mysqli и DateTime были бы наследниками BasicClass. Такая реализация имеет, конечно свои недостатки но мне представляется более логичной чем трейты.
Это нормально
Именно ваше упоминание пяти интерфейсов в статье я понял как недостаток. Простите, если понял неверно.
Но в итоге, какой вывод статьи об отказе от фреймворка? Ито у него плохо, и это плохо…
Yii — неплохой инструмент и если вам с ним комфортно — отлично.
В конце-концов, он практичен. Трудно представить задачу, которую невозможно решить, используя Yii.
Еще Yii невероятно популярен в СНГ. Зная его, очень легко найти как работу, так и сотрудников.
Но если у вас намечается новый долгосрочный проект, обязательно рассмотрите альтернативы.
Не выбирайте инструмент только из-за привычки.
Так отказываться или нет? А то у вас вывод в стиле курсовой троечника — работа проделана, в результате проделывания я написал курсовую.
VolCh
17.07.2017 09:48+2Не все знали. По крайней мере такого описания не встречалось.
Кстати, в посте не об уходе с Yii, а сомнительности решения о старте на нём новых проектов.
kuftachev
17.07.2017 09:48+4Больше похоже на высер, чем на анализ. Вот реально, без рассмотрения конкретных задач, которые принципиально по разному решаются с помощью разных инструментов (в данном случае фреймворков) все это ни о чём!
Кстати, а Вы не думали, куда придется засунуть компоненты с Laravel или Symfony, если потом нужно будет переписать на Java или Go?
По итогу, Yii2 отличный фреймворк, который хорошо справляется со своими задачами. Спасибо тем, кто тратит своё время и силы на его развитие.
VolCh
17.07.2017 11:07Кстати, а Вы не думали, куда придется засунуть компоненты с Laravel или Symfony, если потом нужно будет переписать на Java или Go?
Они, как правило, достаточно изолированы друг от друга и фреймворка, чтобы можно было их легко (особенно если не стремиться сделать полный аналог, а лишь используемые кейсы брать) переписать или найти подходящие аналоги из новой экосистемы. Собственно сейчас многие современные приложения Symfony слабо зависят от собственно фреймворка — его основная цель сейчас по факту обеспечить инициализацию DI-контейнера по конфигам и запустить роутинг, ну и предоставить некоторые хелпер-методы для контроллеров, большинство если не все которых лишь тупые обёртки к часто используемым сервисам из DI.
oleg_gf
17.07.2017 10:34+5Вместо всего можно было просто написать:
Любой фреймворк, который писал не ты — дерьмо!
bores
17.07.2017 11:00+1Стандартные претензии к Yii:
- yii — монолит
- AR хорошо, но нельзя использовать без Yii (см. п.1)
AR мощный паттерн, который в неумелых руках может оторвать, те самые руки. В маленьких проектах с его помощью можно решать следующие задачи:
- Манипуляции с БД
- Валидацию пользовательского ввода (формы)
- Перенос данных между слоями (во вьюхе напрямую)
- Реализация Бизнес-логики
- Поддержка целостности агрегатов (всякие before/afterSave)
Как только проект перерастает сайт-визитку обязательно нужно выделять все эти роли в отдельные объекты, которые могут наследоваться совершенно от разных уровней иерархии Yii:
- бизнес-логика может быть stdObject
- формы хорошо реализуются с помощью Model
- для DTO пойдёт либо массив, либо что-то от Object
- для реализации реализации работы с БД пойдёт ActiveRecord + Mapper + Query. А если поля одиннаково назваются, то реализация DTO на Object избавляет от лишней писанины.
Однако, definitive guide предлагает исплользовать ActiveRecord всегда и везде, что для новичка является большим соблазном запихать в один класс вообще всё. Проходит очень много времени, прежде чем приходит осознание о необходимости деления на слои. Но лень и менеджер с палкой за спиной не дают переделать как надо :) В этом плане более энтерпрайзные фреймворки типа Symfony сразу приучают к правильной организации кода.
Electrohedgehog
17.07.2017 11:28+1А можно поподробнее про валидацию с помощью AR? У меня что-то аж глаз задёргался. Особенно хочу посмотреть примеры валидации телефона и почты с помощью AR.
bores
17.07.2017 11:58+1Я описывал скорее yii-ную реализацию AR, а не Фаулеровскую. Поэтому см. иерархию классов из картинки в посте. Model как раз добавляет rules().
maximkozhin
17.07.2017 13:11Класс(-ы) для таблицы наследуется от AR, который в свою очередь наследуется от yii\base\Model
Валидация в виде метода rules() уже присутствует в yii\base\Model, но в виде «заглушки» (возвращается пустой массив). Метод переопределяется в классе-наследнике AR, на основе типов данных самой таблицы.
А уже далее можно еще раз наследоваться (причем неоднократно), для REST модели, для ORM-модели, для модели формы и так далее. А уже в каждом из этих наследников можно переопределять/дополнять правила валидации, правильно составляя массив, возвращаемый методом rules()
SamDark
17.07.2017 11:43Definitive guide не предлагает использовать AR всегда и везде. Наверное, надо добавить ещё больше сносок про то, что это везде и всегда не надо… если есть идеи, куда именно и в какой форме — дайте знать.
nefone
17.07.2017 11:44Прям разнесли Yii фреймворк, а я его только хотел начать учить.
SamDark
17.07.2017 11:49+2Так можно разнести практически любой фреймворк. У каждого из них есть недостатки. Какой-то лучше в одном, какой-то в другом. Например, Symfony хорош стабильностью, LTS и позволяет удобно делать абстракцию, но и побуждает новичков делать адовый лазанья-код, который будет похуже спагетти. Laravel офигенно быстро релизит новые фичи, но забивает на поддержку и LTS по-страшному. Проекты приходится постоянно переписывать. Ну и так далее.
porn
17.07.2017 14:06побуждает новичков делать адовый лазанья-код, который будет похуже спагетти
Если только новичков, которые до того использовали Yii, и не удосужились прочитать доки.SamDark
17.07.2017 14:53+1Ой не. Кроме доков, чтобы хорошо выделить точную, минимальную и достаточную абстракцию, нужно ещё и много опыта, который к знанию того или иного фреймворка отношения не имеет.
nekt
17.07.2017 12:39+1имею два года опыта писания на yii2, сейчас ковыряю ларавель. Основная претензия к юишке — фреймворк мог бы быть и получше. Боле-менее четкие критегии к «получше» стали появляться в конце первого года работы с ним. Так что далеко не все так печально, как кажется после прочтения.
Тот же ларавель в этом плане у меня пока что оставляет впечатление, как фреймворк для микросайтов. Может это конечно говорит отсутствие опыта в нем, но юишка изначально помощнее будет. И схема построения монолитных крупных приложений там из коробки в рамках использования advanced template, components, modules предлагается очень и очень достойная.AstRonin
20.07.2017 02:01о, у меня абсолютно те же ощущения, когда столкнулся с ларавелом… какой-то сырой он…
AlexLeonov
20.07.2017 10:34+1Сырой? Это вы очень мягко выражаетесь :)
Он совершенно нелогичный и, как бы это сказать… «антипаттерный» что-ли? Думаю, вы меня поняли ))oxidmod
20.07.2017 10:44Ларавель же не интерпрайз ниразу. Он позиционируется как фрейм-ворк для ремесленников. На нем быстро и удобно раз-раз и в прод. При этом от Yii он выгодно отличается использованием большого количества сторонних компонентов. Если немного поколдовать то с него выйдет полноценная симфони, если вдруг проект выстрелит и потребуется техдолг сократить и переписать посолидней както
AlexLeonov
20.07.2017 11:00Как говорил мой давно покойный дед: «тяп-ляп, насрал и
в продакшнгречневая каша» (с)
nekt
20.07.2017 13:52вот сейчас я переписываю его на «посолиднее»… связка репозиторий-презентер-трансформер-модель выглядит вполне себе солидно, но чесслово, контрактное программирование и SOA по скорости разработки, солидности и прозрачности оставят его далеко позади.
michael_vostrikov
20.07.2017 23:32Это да. Недавно с ним работаю. То, что сходу вспомнилось:
- Ошибки формы принято передавать через flash-переменные сессии с редиректом. Повторно форму не отправить, после обновления страницы все ошибки стираются.
php artisan make:auth
. Какая-то запутанная система с кучей трейтов разной вложенности.- Eloquent пихает created_at, updated_at в каждую сущность, и оставить какое-то одно из них это проблема.
- Фасады и глобальные функции.
Route::get()
, реализацию так сходу не найдешь. Глобальные функции просто как-то смущают.
Зато middleware удобная концепция, в Yii было бы неплохо их добавить.
jetexe
21.07.2017 08:19Ошибки формы принято передавать через flash-переменные сессии с редиректом. Повторно форму не отправить, после обновления страницы все ошибки стираются.
Ajax валидация из коробкиmichael_vostrikov
21.07.2017 10:41+1Как flash-переменные помогают ajax-валидации?
loveorigami
22.07.2017 00:22Например, так
https://github.com/loveorigami/yii2-notification-wrapper
Акцент на слове «помогают»
jetexe
24.07.2017 08:47Видимо я не совсем понял о чем вы. О какой ошибке идет речь если данные на форме валидируются до отправки? Если вы про ошибку сервера, то тут любой вариант кроме исправления является не правильным
michael_vostrikov
24.07.2017 09:06Вы хотите сказать, что если на фронтенде данные провалидировались js-скриптом, то на сервере их проверять необязательно?
jetexe
24.07.2017 12:56Вы хотите сказать, что ajax валидация это валидация JS скриптом? или всё-таки данные формы проверяются на сервере?
michael_vostrikov
24.07.2017 14:33А что значит "данные на форме валидируются до отправки"? Ajax-валидация это отправляем данные с формы через ajax, сервер их проверяет, получаем в ответ json с ошибками. Сессия тут не нужна.
jetexe
24.07.2017 15:51да, так оно из коробки и работает…
(«отправкой» называл submit формы)michael_vostrikov
24.07.2017 16:27Так для этого не нужны flash-переменные и редирект. Как они помогают-то?
Fesor
24.07.2017 21:15они помогают просто при валидации. когда у вас отключен javascript например. Для валидации без перезагрузки страницы они на самом деле не нужны. Только для отображения ошибок после submit формы.
kowap
17.07.2017 13:32+1Так когда Yii 3.0? ))
SamDark
17.07.2017 14:55Порциями. Первые порции уже завезли. Остальные продолжают завозиться по мере поступления.
rsvasilyev
17.07.2017 15:19Александр, выше вы уже рассказывали о планах на 2.1:
Будем облегчать ядро, избавляться от всяких jQuery, выкидывать версии PHP до 7-ки, выкидывать HHVM. Выпиливать части в расширения и независимые библиотеки, которые, по возможности, будут поддерживаться заинтересованными разработчиками. Облегчать дерево наследования и стремиться выпилить его совсем…
Революции вроде 1.1 > 2.0 не хочется. По крайней мере пока.Облегчать, избавляться, выкидывать, выпиливать — это больше о рефакторинге.
kowap спрашивает о 3.0. О новых фичах, которые будут сделаны лучше, чем у конкурентов.
Вы можете привести примеры таких фич?
В багтрекере в 2.1 и 2.2 на первый взгляд таких фич не видно.
SamDark
17.07.2017 15:38+4У нас уже есть фичи лучше конкурентов — генерация кода, query builder, AR (если выбирать из реализаций AR, конечно), i18n, RBAC, дата-провайдеры и гриды, active form, phpdoc в коде и дока. Некоторых из этих фич у других просто нет.
В загашнике есть новый роутер и контейнер, но не факт, что они вообще увидят релиз потому как то, что уже есть сейчас, довольно хорошего качества и смысла выпускать то же, но своё, никакого.
Задача 2.1 не добавить тучу киллер-фич а наоборот: ввести больше интерфейсов, чтобы использовать больше качественного стороннего кода, выкинуть часть своего кода и почистить то, что осталось. Это будет уже качественный рывок вперёд потому как набор относительно уникальных фич, которые мы сделали хорошо и ради которых стоит использовать именно Yii, есть.
Samouvazhektra
21.07.2017 12:30+1Очень хотелось бы чтобы магию событий и поведений разнесли по трейтам с интерфейсами… и валидацию… по умолчанию пусть все использует. но чтоб можно было ненужное выкинуть и получить чистенький класс только с реляциями. Вообще-то как-то заморачивалась с этим — получились трейт магии аттрибутов, поведения+бихейворы — тяжко делить из за постоянного ensureBehaviors(), и валиадации которые навешивались и функционировали на чистом классе, но на реализации чистого ActiveRecordInterface мозг вытек в перенаследованиях магии и инициатива скисла.
eawapownikov
17.07.2017 15:36Я считаю механизм создания админки с помощью gii очень удобным, с минимальным ко-ом магии и быстрым для маленьких проектов и прототипов. Gii генерит код, потом его подпиливаешь и все понятно как работает. Так же очень крутой у yii это виджет gridview. Плюс это хозяйство поддерживается coreteam.
Демо gridview: http://demos.krajee.com/grid-demo
Вопрос сообществу — есть ли такие аналоги у symphony и laravel? Так сходу достойных аналогов у них я не нашел.
И у кого какие мнение по поводу такого построения админки?Voenniy
17.07.2017 15:59Ларавел — https://sleepingowladmin.ru/
michael_vostrikov
17.07.2017 21:01+2Она сама как фреймворк) С аналогичным объемом документации.
https://sleepingowladmin.ru/docs/model_configuration
Ниже приведен пример того, как может выглядеть конфигурация модели:
AdminSection::registerModel(Company::class, function (ModelConfiguration $model) { $model->setTitle('Companies'); // Display $model->onDisplay(function () { $display = AdminDisplay::table()->setColumns([ AdminColumn::link('title')->setLabel('Title')->setWidth('400px'), AdminColumn::text('address')->setLabel('Address')->setAttribute('class', 'text-muted'), ]); $display->paginate(15); return $display; }); // Create And Edit $model->onCreateAndEdit(function() { $form = AdminForm::panel()->addBody( AdminFormElement::text('title', 'Title')->required()->unique(), AdminFormElement::textarea('address', 'Address')->setRows(2), AdminFormElement::text('phone', 'Phone') ); return $form; }); }) ->addMenuPage(Company::class, 0) ->setIcon('fa fa-bank');
Сложновато как-то выглядит. И кастомизировать сложнее, чем HTML + GridView/ActiveForm.
oxidmod
17.07.2017 16:02Ну для симфони есть Sonata и EasyAdmin
Sonata вообще довольно гибкая и расширяемая в лучших традициях симфони.
EasyAdmin к сожалению не пользовал сам, но по отзывах весьма и весьма неплох.
По сабжу статьи:
Yii пытается быть комбайном и делать все… Делать все хорошо довольно трудно. В тоже время Symfony просто хорошая платформа, на которую легко и просто можно затащить все что нужно и заменить любую деталь
Dima_IT-Tech
17.07.2017 16:42+2Если не привязываться к basic или advanced шаблонам, то можно довольно легко на базе yii реализовывать достаточно сложные с точки зрения архитектуры приложения.
Alexsey
17.07.2017 16:50-1Лично я со скрипом, но все же перехожу в своих проектах с yii на asp net core, благо опыт разработки на c# достаточно большой. Все более-менее устраивает, не хватает только lazy loading в ef core и не понятно когда он будет, но при желании это решается костылями.
voidshah
17.07.2017 20:10Меня еще иногда напрягает то, что в конфигурациях компонентов все свойства публичные… И это позволяет всякие нехорошие вольности… Ну и DI… Ларавелевский куда мощнее и юзать его гораздо более приятнее — тот же request в action контроллера пробрасывать куда проще. А в Yii либо $request = Yii::$app->request (про вездесущий Yii::$app уже говорено много), либо инжектить через конструктор контроллера.
michael_vostrikov
17.07.2017 21:20+2Yii неплохой фреймворк для «стандартного» программирования на PHP (PHP, MySQL, Bootstrap, jQuery).
Он несложен для освоения начинающими, но и позволяет делать серьезные рабочие проекты.
У него есть недостатки, в каких-то проектах они имеют значение, в каких-то не очень.
Rathil
17.07.2017 23:05Сейчас все новое начинаем на Фалконе. От Yii и Yii2 решили отказаться.
DeLuxis
18.07.2017 07:21+2Смысл? 7.1 сейчас достаточно шустр.
nekt
20.07.2017 13:54фалкон, протон, пхпреакт предлагают качественно новый уровень скорости и возможностей. Без них нормальные сервисы не слепить. Демонизация — шаг в будущее.
DeLuxis
20.07.2017 14:17Безусловно. Если надо быстро сварганить рантайм приложение для PHP сайта, — годится.
Если надо на постоянку, да еще высоконагруженное, я скорее задействую Golang, ну или на C\C++ напишу.
Просто сейчас уже имеется прототип с демоном на morozovsk/websocket от morozovsk. Я рассматривал варианты на что переписывать серверную часть websocket, пробовал писать небольшие тестовые чатики на всяких решениях, и лучше Golang пока ни чего не нашел. Есть еще у C\C++ красивые решения, но там придется больше времени убить.
PHP для высоконагруженных и масштабируемых решений не годится. Вообще ни как. Даже монстр nodejs лучше смотрится.VolCh
20.07.2017 18:18+2Что не так с нагрузкой и масштабированием у PHP? Демонов на нём писать — спорное решение. А уж служить stateless прокладкой между веб-сервером и базой что ему мешает? Да, накладные расходы могут быть выше чем у других решения, например, true fastCgi, но что мешает горизонтально масштабироваться, если время единичного ответа устраивает? Ну, пускай 20 серверов надо будет, а не 10, как для nodejs.
Samwolf
18.07.2017 09:04+1Yii forever
если думать что когда придет Yii3 4 5… то фреймворк будет все делать за вас сам. не угадали.
Yii впервую очередь инструмент и каркас на который можно вешать всю архитектуру. Здесь все зависит от того как использовать инструмент.
и чем мешают Yii::$app просто не используйте(создайте свой велосипед). я не вижу здесь проблемы.
а отношения composera и Yii обсуждать имхо, совсем не нужно. Насколько я знаю composer создан для PHP а не для Yii. https://habrahabr.ru/post/145946/ExileeD
18.07.2017 12:39Проблема в том как бы мы не хотели не использовать Yii::$app, мы не можем это сделать. (без костылей) У половины стандартных компонентах нет интерфейсов что бы прокинуть в класс.
SamDark
18.07.2017 12:50-1Класс — тоже интерфейс.
ExileeD
18.07.2017 12:54+1Ну кидать реализацию например кеша имхо не стоит, для меньшей связанности. А интерфейс прокинуть толком не сможем, его нет. Можно создать свой интерфейс, но это костыль, и мы на него наткнемся если завтра нам нужно взять сторонний кеш.
SamDark
18.07.2017 13:27+1А ещё можно в issue сделать запрос на интерфейс. Или pull request сразу, если работы не много...
sergey_novikov
20.07.2017 17:18Первый и последний раз, когда я попытался что-то закоммитить в Yii1, PR не получил никакого вообще ответа за 4 года. Ощущение, что отправил в /dev/null :-)
Для сравнения, в Symfony мой PR прокомментировали по существу в течение дня и вскоре смержили.SamDark
20.07.2017 17:23В 2013-м было? Такое происходит очень очень редко, если сейчас вообще происходит. Как минимум мы читаем, планируем milestone и, скорее всего, комментим сразу сейчас.
sergey_novikov
20.07.2017 17:32Да, в 2013. Потом компания мигрировала на symfony и поводов коммитить больше не было. Рад, что ситуация сейчас улучшилась.
jetexe
20.07.2017 17:51+1Для сравнения оба моих PR в Yii2 смержили один за 4 дня (с некоторыми исправлениями), второй на следующий день после комита
AstRonin
20.07.2017 19:09+1я вот для второго Yii когда фикс присылал, довольно оперативно все сделали, с несколькими правками вроде как за день все осилили
kraso4niy
18.07.2017 09:04+1В поддержку уии скажу что 1.x версии были хороши.
Но уже тогда было понятно что нужно знать и yii и sf: )
И ждать кто же победит.
Для меня и многих компаний победил сенсиолабс и его компоненты.
Сейчас если вы не способны собрать свой yii2 за 2 дня, то пожалуй вам нужно использовать этот фреймворк.
Для остальных есть composer: )
AlexLeonov
Не стоит даже и задумываться. Фреймворку, который игнорирует публичные общепринятые стандарты — место только в истории.
Скажем ему большое спасибо и, наверное, распрощаемся.
SamDark
Какие именно стандарты?
AlexLeonov
В данный момент семейство общепринятых публичных стандартов для фреймворко-строения у нас одно — это PSR.
А если идти еще глубже, есть те же принципы SOLID, которые, наверняка, вам прекрасно известны.
SamDark
Про PSR в Yii в курсе. Мы участвуем в PHP-FIG и эти самые PSR помогаем писать. Когда Yii 2.0 релизился, многие PSR ещё не были приняты, а после релиза ломать работающий код в минорных версиях — это не наш метод. В следующей мажорной версии PSR будут использоваться более широко. Вот текущее состояние: https://github.com/yiisoft/yii2/wiki/PSR-adoption
AlexLeonov
Имхо, уже будет поздно.
SamDark
Почему?
AlexLeonov
Потому что на данный момент скорость развития кодовой базы Yii стремительно отстаёт как от языка, так и от стандартов и других фреймворков.
Вам выше уже всё сказали — зачем, к примеру, пилить свой, какой-нибудь к примеру FileSystemHelper, если есть множество готовых, устанавливающихся одной командой composer? А на это тратится безумное количество времени.
При этом всём никаких киллер-фич в Yii нет. Ну кроме, разве, явного указания лэйаута для страницы в контроллерах :) Но это уже скорее из разряда «жесть», нежели «фича».
SamDark
Конкретно FileSystemHelper — только обратная совместимость. Некоторые другие части Yii, которые есть где-то ещё, потому что они получились лучше, чем где-то ещё.
Ну и плюс тут вопрос контроля и хрупкости. Вспомните left-pad и npm...
Fortop
Даже без сарказма.
Можно узнать о этих некоторых других вещах?
SamDark
https://habrahabr.ru/post/333398/#comment_10315796
Vamp
Реальность показывает иное.
SamDark
Бывают исключения.
Dima_IT-Tech
Там вроде из принятых только PSR-3 не соответствует