Недостатки laravel

Я очень люблю фреймворк laravel, пользуюсь им начиная с 3-й версии, тогда он был как глоток свежего воздуха на фоне zend и symfony. Уважаю Тейлора за проделанную работу, за принесённую в php фреймворки идею удобного апи и умение копировать лучшее из других фреймворков вроде RoR. О плюсах сказано уже много, но у него есть свои недостатки.
Well, nobody perfectЭти недостатки не фатальны, а некоторые и вовсе мои личные привычки, которые другим покажутся надуманными. Всё дерьмо вылитое ниже не сильно влияет на мою оценку laravel, который считаю лучшим фреймворком в мире PHP. И спасибо @kotchuprik и его статье, который подтолкнул высказаться и дал некоторые идеи.

Фасады и статика, они везде, даже в начале  проекта у вас уже в routes.php есть Route::get и это при наличии хорошего DI, который позволяет отказаться от этого и получить нормальный автокомплит в IDE. А так приходится ставить IDE Helper. Почему-то комментаторы набросились на этот пункт, начали меня оскорблять и учить, но недобитый фасад из коробки есть, я не виноват.

Непоследовательность. Фреймворк очень долго переходил на PSR, но так до конца не перешёл. В папке database творится полный бардак. В app прямо в корне лежит моделька User. Роуты валяются в файлике app/Http/routes.php. Шаблоны расположены в директории resources, в отрыве от остального app. Предпочитаю когда есть директория с модулем, а уже в ней контроллеры, модели, шаблоны и т.д. А так получается каша, где все контроллеры свалены в кучу, с которой сложно работать на большом проекте. Сразу начинаешь оформлять код как пакеты, но появляется неудобство с прописыванием дополнительных путей для консольных команд.
Консольные команды и контроллеры почему-то разные сущности, при этом контроллеры вовсе отправлены в папку Http с роутингом и мидлеварами. Всегда считал что консоль должна работать так же как и при запросе из браузера и делал синтаксис.

console news/1
console user/1/store --method=post --data="name:Petja, login:God"

Отсутствие базовых классов для Model, как это есть для контроллеров, запроса, событий. А вот модельки при генерации наследуются от модели из вендора, что создаёт трудности с расширением, приходится править цепочку наследования после кодогенерации.

Версионирование. Между версиями большие изменения, при этом в минорных релизах умудраются убивать обратную совместимость, например, убрав метод list из моделей между 5.2 и 5.3, а не подождав до 6-й и там отрубив deprecated. Хотя сейчас есть LTS версия, но на ней мы уже ловили баг с роутингом, правда виной тому был вендорский пакет от symfony.
Есть древний принцип версионирования http://semver.org/lang/ru/, согласно ему минорная версия лишь добавляет функционал не ломая обратной совместимости.

Миграции. Они до сих пор не по psr и без немспейсов, название класса не совпадает с именем файла из-за чего возникают коллизии. Например, у вас был раздел новости и таблица под него с миграцией

php artisan make:migration create_news_table --table=news

Создаст файл 2014_01_01_000000_create_users_table.php с классом CreateNewsTable, затем этот раздел убрали, а церез год вернули, но он уже работает по другим правилам и содержит другие поля

php artisan make:migration create_news_table --table=news

2015_03_06_000000_create_users_table.php с тем же классом CreateNewsTable.

Отладка. Из коробки отсутствует дебаг панель, её нужно устанавливать отдельно. Не очень хорошо подменён error_handler, из-за чего в дев режиме иногда видишь белую страницу и нужно лезть в логи, чтобы узнать что права на папку не прописал. В том же дев режиме почему-то не логируются запросы к БД, из нужно руками включать через те же фасады \DB::enableQueryLog();

Elixir — не понимаю зачем Тейлор всунул из коробки эту нодовскую приблуду. Можно было прикрутить assetic или его аналоги, а там уже пусть разработчик через конфиги решает собирать ему всякие less c помощью php или node-ruby утилит. Assetic справляется с этими задачами, а проектах с большим количеством фронтенда всё равно пользуются webpack и grunt.

Формы. Почему-то выбросили компонент для работы с формами, теперь приходится пользоваться LaravelCollective, который является сторонним компонентом, а сам фреймворк не поддерживает функционал необходимый в каждом веб приложении. Для REST формы не нужны, но как раз ради этого кейса Тейлор создал отдельный фреймворк Lumen. А так laravel проигрывает на фоне других фреймворков не имея решения для форм из коробки.

Eloquent работает со связанными таблицами не через джойны, а с помощью IN, это весьма неудобно если например нужно отсортировать данные по связанной таблице — новости по колличеству комментариев.
Так же есть магические файндеры вроде where<field>(<value>) whereUsername(‘AmdY’), это очередной способ отстрелить себе ногу.
Модель это мусорка в которое объеденились:
1. Непосредственно сама модель и её методы, мутаторы
2. Коллекции для работы с набором моделей, итерирование, сортировка, фильтрация и т.д.
3. Построитель запросов select, where, take, get, all
4. Пагинатор paginate, append
5. Скоупы
6. Менеджер подключений setConnection, onWriteConnection …
Многие методы и атрибуты статические сообветсвенно распостраняются на все объекты класса.
7. Связи hasOne, hasMany ….
8. Observer и методы creating, created,deleting и т.д. При этом эти методы так же статические и задевают все модели
9. Работа с event-ами
10. Сериализация, при этом только json, стратегии нельзя задавать
Скоупы, не понимаю зачем они нужны, они ломают автокомплит, вешаются на весь класс, а есть ещё глобальные скоупы.
Отсутствие схем и возможности нормальной рефлексии для моделей, позволяющие строить автобилдеры для форм и списков, даже список связанных моделей нельзя получить.

Blade. Непонятные вещи творятся с шаблонизатором, выбран очень странный путь его развитие с внедрением опасных конструкций  @inject и @php, следующим шагом будет @eval и @goto? При этом нет удобных средств для контроля цикла foreach, чтобы узнать первая-последняя итерация или её номер. Делать такое приходится через вставку php кода <?php $i++; ?>. Ну и отсутствие режима песочницы, из-за возможности использования php тегов а так же @php, @inject наши шаблоны опасны и нельзя делать безопасные шаблоны-темы, так как они подвержены php injection.

Установка пакетов. В laravel 3 бандлы можно было устанавливать из командной строки, сейчас же вам нужно:
1. Зайти на документацию по пакету
2. Добавить пакет через composer
3. Прописать его в providers
4. Добавить alias для фасадов. Так лучше не делать, но иногда фасады это единственный способ переопределять статик ад в пакетах.
5. Импортнуть конфиги-вьюхи, миграции, сиды и т.д.
Для 4-ки была идея специального установщика, но видимо она так и не попала в пятую.

Роутинг.  Нужно прописывать все роуты вручную, исключения составляют ресурсы. Раньше был метод controller (в 5.2 deprecated, в master уже нет), который автоматически делал роуты для целого класса, но его убрали. Кроме того невозможно задать схему /module/controller/action, приходится делать специальный роут {module}/{controller?}/{action?} который всё это перехватывает и вручную инициализиуется контроллер и дёргается метод.

Тесты. Если у вас установлен глобально phpunit, то без бубна тесты им не запустятся. Очень бесило то, что не работали обсерверы в моделях при тестировании, сейчас это починили. Ну и не нравится очередной велосипед вместо проверенного Codeception.

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

Поддержка. В один прекрасный день Тейлор взял у убил все issue на github, такое отношения к багам пугает. LTS появилось очень поздно, лишь на версии 5.1. Ну и развитие идёт по пути того, что надо авторам для их проекта, а не под нужды сообщества.

Джуниоры. Свой кажущейся простотой фреймворк привлекает кучу новичков, которые не могут освоить даже документацию к фреймворку, composer, разобраться с автозагрузчиком и научиться устанавливать document root. Вот типичный пример таких джуниоров, которые даже синтаксиса языка не знают.

p.s. Подбрасывайте ещё недостатки, буду добавлять их в статью чтобы собрать в одном месте, а не ныть постоянно по мелочам.

Набрасывайте

Недостатки laravel: 16 комментариев

  1. Eugene

    Автор прав. Полностью солидарен.

    Да и разработка идет таким образом: Тэйлор открыл гитхаб, принял пулы, закрыл гитхаб.
    На этом всё.

    1. AmdY Автор записи

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

  2. Роман

    Пост должен был называться «что мне не нравится в laravel».

    Согласен с пунктом «Отладка» — ибо правда — исключение выскочившее до подмены хендлера, не будет обработано должным образом. Но это даже багом не назвать.
    Так же согласен с тем, что Eloquent далек от идеала. Да что уж там — он настоящая какашка (удобная такая, с креслом и подлокотниками ). Но касательно «ёлки» поддерживаю не по всем пунктам, так как большинство из них просто описывают идею ActiveRecord, и отдельно Eloquent тут не причем).
    И лютый наплыв джунов подтверждаю, но не вижу в этом проблемы.

    Всё остальное — просто высосано из пальца.

  3. Александр

    Вообще не понял Laravel, все через одно место. Если даже нет поддержки форм из коробки, зачем вообще такой фреймверк нужен.

  4. Smily

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

    Вот еще одна странная штука, Translations — взяли из Symphony и зачем то напутали с группами, модулями и токенами. Переопределили всё напрочь, когда хотел сам переделывать на бд, пришлось возвращать то как было в Symphony …

    По поводу Тестов согласен, нужно бить в бубен. Но Codeception как таковой я не очень люблю, мне по-нраву простой Selenium. Оффтоп конечно, но смешно, на Laracasts, чтобы просмотреть туториал как прикрутить Selenium нужно платить, меня это задело. А документации на эту тему маловато.

    Еще, почему я каждый раз как решаю проблему ( работа с шаблонами, подсказки в IDE, ассеты, работа с HTML, и тд ) должен лезть за новым расширением, причем стороннем. То есть меня пугает кол-во сторонних расширений которые я ставлю… Особенно, когда речь идет о большом проекте. Если автору расширения надоест поддерживать его, что мне делать?

  5. Smily

    Да еще момент забыл упомянуть, ядро очень плохо прокоментированно.
    Как минимум базовый класс лишен phpdoc для динамический элементов Config, Route и т. д. Также и с фасадами, зачем они к черту нужны если у них тоже нет phpdoc, и они все равно загружают то что храниться в Application ( тут в меня, кидают тухлым _ide_helper ). То есть я новичок в Laravel, но далеко не новичок в web-development (я люблю посмотреть ядро ).

    Ок, я генерирую модель для таблицы, камень в Artisan, и знаете что, я получаю просто пару строк кода (без phpdoc), которые за меня написал бы любой IDE. Зачем он к черту нужен …

    Вот еще что меня клинит, простите но я не вижу php framework как микросервис, и не понимаю, новой тенденции делать глобальную Event систему — что за х… То есть по сути я могу в любой части фрэймворка (опустим, то что предлогается в документации ) подписаться на event — это как понимать, — зачем? Если придет Некто Васькин, и напилит в своей модели Event на Другую модель, я ж в жизни не пойму — почему там значение меняется ( ну или логику, которая будет в event прописана)

    Вспомнил еще самое критичное — кэш. Сегодня пользуюс 5.2 И знаете что, когда создается кэш, он создается вот так

    > return file_put_contents($filename, $data);

    Что тут плохого, да то что вы из консоли его не удалите. И хотя вы упорно будете ставить в сам вызов 0777, он все равно создастся с правами 0644. Дело в том? что ребята забыли про umask !. И когда создается вот так вот через return file_put_contents … то umask вежливо берет и отнимает в соответствии с политиками безопасности, все опасные права ( в том числе и на удаление ).
    Как же нужно было сделать :

    > file_put_contents($filename, $data);
    > return chmod ($filename, $rights ); //…

    Но ладно бы еще это, еvent «до» есть, event «после» — нет, иными словами мрак. Решение которое мне предлагают, создайте консольного пользователя, с группой веб-сервера — что? Вы хоть понимаете, что это не правильно …

  6. Сергей

    Если будет время и желание, могли бы раскрыть подробно тему, что не так с фасадами? Почему это плохо?

    1. AmdY Автор записи

      Плюсов гораздо больше, фреймворк на несколько порядков ускоряет разработку. Я уже писал о плюшках, но это было давно и для версии 4 http://amdy.su/laravel-4/, с тех пор плюшек стало больше. В то же время в новых версиях уже поправили часть минусов из данной статьи, вроде циклов, при этом сделали даже больше, чем у меня было в хотелке.

  7. Vasiliy

    «нет удобных средств для контроля цикла foreach, чтобы узнать первая-последняя итерация или её номер. Делать такое приходится через вставку php кода »
    Странно, а здесь написано что можно:
    https://laravel.com/docs/5.3/blade

    1. AmdY Автор записи

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

  8. Андрей

    Здравствуйте,
    Актуальны ли перечисленные проблемы для версия 5,4. После долго работы на yii 2 решил глянуть на laravel и как то перечисленное отбивает желание вообще с ним возится…

  9. Андрей

    Пытаюсь перейти с Yii2 на Laravel. Yii2 хорош, прост, на ура поддерживается IDE, но там много самописного. Он не учит общепринятым компонентам и современным паттернам.

    Сейчас в Laravel 5.4 большинство проблем уже решено.

    Но отсутствие роутера на весь контроллер действительно раздражает.

    Eloquent в 5.4 имеет методы join, joinLeft и т.п. которые организуют джойны с явно указанными таблицами. Я использую with() вместе с joinLeft(). Причем ставлю алиас для join по имени relation. В итоге работает и сортировка и фильтрация из frontend напрямую без всякого маппинга полей. И видимо лучшего решения я не найду.

    Поддержка форм на backend и компоненты типа Elixir нужна только джуниорам. Нечего там делать этой утопичной функциональности. Познакомьтесь с angular, gulp, webpack. Поймете о чем я.

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

    Фасады странные. Согласен. ide_helper вообщем-то не спасает на 100%. Вот это наверное единственный фактор, из-за которого я сомневался при переходе с YIi2.

    Также мне не хватает функциональности типа behavior в Yii2.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *