Обновить
30
Пётр Грибанов@ghost404

Symfony professional developer

19
Подписчики
Отправить сообщение
Ну например на любой роут с методом OPTIONS стоит возвращать 200ый ответ, а на любой роут после всех — 404 с красивой картиночкой.

Это есть из коробки. Если роут не найден — 404. Страницу 404 можно кастомизировать. Все ответы по умолчанию отдают 200


Это не коробочный симфони, если не путаю, это SensioBundle или что-то такое.

Sensio входит в стандартную поставку Symfony. Ссылку вам давали выше.

Префиксы в том же месте, где и роуты (не вынося в отдельный yaml)

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


Одной строкой задекларировать полный CRUDС

Аналогично в Symfony. Но нормальные проекты не ограничиваются только CRUD-ом. А когда мы говорим о DDD, то CRUD, вообще перестает быть актуальным


вязать с рантаймом (например выгрузить из БД, бред конечно, но мало ли)

Это удар по производительности и нужно разьве что для CMS. В Symfony это тоже можно сделать, но зачем?


Объявлять паттерны для плейсхолдеров для всей группы (или вообще глобально)

Пожалуй согласен. В Symfony этого нет. Объявить регекспы один раз, а не в каждом роуте может быть удобно, хотя реализация в Laravel мне не нравится. Ну и можно вообще отказатся от регекспов, так как всё равно маппинг делается на сущность.


А можно связать плейсхолдер с любой сущностью (например выбрать из БД энтити, как в симфони в контроллерах)

Это ParamConvertor, о котором я уже говорил ранее. Он удобнее чем в Laravel


А ещё раньше можно было одной строкой замаппить все роуты на паблик методы контроллера (задепрекейтили в 5.1, вроде, и вырезали в 5.3)

И правильно сделали


И самое главное у роутов есть приоритет. Аннотациями приоритет не сделать, приходится гибрид фигачить.

  1. Приоритет определяется порядком определегия.
  2. А зачем вообще приоритет роутингов? Если роутинги могут конфдиктовать, то у вас серьезные проблему в проекте

То есть, большое количество предустановленных компонентов в фраймворке которые будут не нужны большинству вы считаете плюсом?


Вы мне напомнили сейчас M-A-XG (нынче он http3) который хает фраймворки потому что в них нет хлебных крошек.


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

Этот роутинг аналогичен именно симфонёвому, в Yii он иной, но при этом он гибче симфонёвого, но и многословнее.

А чем он гибче и многословней? Прочитал документацию. Абсолютно всё тоже самое, что и в Symfony. Только группировку в Symfony реализуется подругому, чуть более логчно, и ParamConvertor в Symfony удобнее. Поделитесь пожалуйста, чем роутинг в Laravel лучше чем в Symfony?


А в Laravel есть лоадеры

Под переводами в Doctrine я имел в виду не хранение переводов в бд, а автоподстановку переводов полей сущности:
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/translatable.md


можно даже не писать, а использовать готовые вещи
добавляете новый адаптер (лоадер)

О чем я и говорю. Добавьте в Laravel фарша из Symfony и получите Symfony.


Почему же более мощный DI — это плохой вариант IoC?

Описанные вами примеры это хороший способ усложнить сопровождение проекта или выстрелить себе в ногу.


Получить сервис по интерфейсу

Это просто эпический ад. Интерфейсы описываю контракт, который реализует один или более классов (как правило более одного). И как же Service Locator будет резолвить разные сервисы с одним интерфейсом? Да никак. Бам. О, моя нога)))

Таких подробностей я не помню. Смотрел на него несколько лет назад когда он только появился на хабре.

Я сравнивал Yii 1 и Laravel 1, когда он только вышел.
Что мне сходу не понравилось в Laravel:


  • дурацкая файловая структура. Мне на тот момент она показалась не логичной.
  • работа с базой через такой же ActiveRecord что и в Yii. Принципиальных преимуществ я не увидел, особенно если сравнивать с Doctrine.
  • мне не понравился шаблонизатор. Не да Twig, пере php как в Yii, но это субъективное. Twig мне нравится больше.

Сейчас бегло пробежался по документации и увидел ещё проблемы:


  • роутинг через php. Тоже что и в Yii. В Symfony роутинг конечно тоже транслируется в php, но описываем мы его либо в yaml конфигах, либо в аннотациях.
  • аннотации считаю очень удобным инструментом, хоть и не всегда они к месту. В Laravel аннотаций я не увидел, возможно нужно было капнуть глубже.
  • переводы в Laravel описываются в php файлах как и в Yii. Удобно использовать формат xliff, для которого есть редакторы и можно отдавать переводы на сторону — переводчикам, не разработчикам. Также удобным является формат yaml, позволяющий построить иерархию сообщений.
  • для Doctrine есть бандл который позволяет переводить сообщения из БД
  • реализация IoC в Laravel мне показалась странной. В Yii не лучше.

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


Laravel и так написан на компонентах Symfony, если в него перенести Doctrine, Twig и еще кое какие компоненты из Symfony, то от самого Laravel почти ничего не останется и логичнее сразу писать на Symfony.


В результате, я не увидел никаких преимуществ Laravel и Yii перед Symfony. Если я что-то упустил, просветите меня пожалуйста.

Согласен. Было бы интересно посмотреть на что-то лучше Symfony)))

Работал с Zend 1, Symfony 2, Yii 1 и самописными фраймворками.


Как-то пришлось начать проект на Yii 1 после Symfony 2.
Год разработки я плакал горькими слезами (буквально).
Даже если очень захотеть, не говнокодить на Yii почти невозможно.


Смотрел Laravel. Тот же Yii вид сбоку.


Уже несколько лет я на Symfony и счастлив как ребенок.
DDD + CQRS + Specifications + ValueObject + Doctrine


Даже маленькие проекты на Symfony летают.

Правильней говорить:


Сейчас все актуальные фреймворки перешли на компонентны Symfony)))

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

Я кинул пару PR в myclabs/php-enum, может вам пригодится

По собственному опыту скажу что XAMPP не лучшее решение.
Это только базовый веб-сервер.
Потом понадобится поставить Redis, Ruby, Java, SASS, Sphinx, Elasticsearch, APCu.
И весь этот зоопарк поддерживать на винде, никсах и маках.


С точки зрения разработки, Windows имеет массу недостатков. К описанным nitso проблемам, добавлю:


  • тормоза Symfony на винде из-за особенностей файловой системы. APCu и OPcache помогают, но не спасают. Все равно скорость в 3 дольше. Использование встроенного php сервера просто самоубийство.
  • частые проблемы с регистром имен файлов. Изменить регистр имени файла в git приходится делать 2 коммитами.
  • сталкивался с тем, что MySQL в XAMPP работает не так же как и на CentOS и запросы которые на Windows проходили без проблем, ломали боевой сервер. Или данные хранились не в корректном формате.
  • частая ситуация когда на винде все работает, а на никсах нет

Уведомления не доходили потому что нужно было еще прописать messaging.onMessage().


Сейчас все поправил и сделал полноценное приложение с отправкой уведомлений через js

И да, вы правы ограничения есть, однако это не это не равно утверждению "с рефлексией этого сделать нельзя".

Если ограничения не позволяют нам что-то сделать, значит это сделать нельзя. Разве нет?
Если ограничения накладываются в результате использования рефлексии, то значит "с рефлексией этого сделать нельзя".
Вроде все логично.


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

Точно. Вся проблема была в messaging.onMessage(). Теперь я понял почему не работало без него. Добавил обработчик и сразу все, везде заработало.


Спасибо большое.

я с этим не согласился и потом вы мне приводите именно пример что можно! Что то пошло не так?

Как раз я привожу пример что нельзя. myclabs/php-enum воспринимает константы с описанием как варианты значения. Тоесть метод Action::toArray() вернет TITLE_VIEW, что не корректно. Можно объявить TITLE_VIEW как не константу, но это все ухищрения чтоб угодить инструменту, а не бизнесу.


Хорошее решение этой проблемы предлагает библиотека marc-mabe/php-enum, которая воспринимает только публичные константы, но нужен PHP 7.1.


в случая же 2 вы как то сразу схитрили. Зачем метод делать final public static?

Да, схитрил. Естественно. Потому что с точки зрения бизнеса не должно быть final и не final методов. Весь объект должен быть final. А если инструмент требует помечать методы как final, то я вынужден и остальные методы тоже помечать как final, чтоб защитить класс.


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

Спасибо. Добавил ссылки в статью

Это почему нельзя? что мне помешает?

Пример на основе того же myclabs/php-enum. Я добавляю человеческое описание для вывода на frontend


class Action extends Enum
{
    const VIEW = 'view';
    const EDIT = 'edit';

    // константы воспринимаются как варианты значения
    // формат предназначен для перевода
    const TITLE_VIEW = 'acme.demo.action.view';
    const TITLE_EDIT = 'acme.demo.action.edit';

    // можно использовать для radio/checkbox/select
    public static function choices()
    {
        return [
            self::VIEW => self::TITLE_VIEW,
            self::EDIT => self::TITLE_EDIT,
        ];
    }

    public function title()
    {
        return static::choices()[$this->getValue()];
        // можно былоб писать проще и не создавать метод choices,
        // но тогда такую конструкцию тяжелее использовать для radio/checkbox/select
        //return 'acme.demo.action.'.$this->getValue();
    }
}

Можно не добавлять префикс для значения, но тогда теряется контекст. Одно и то же значение в разном контексте может по разному переводится.


Пример на основе antanas-arvasevicius/enumerable-type. Я добавляю свои методы для бизнеслогики


class Action extends EnumerableType
{
    final public static View()
    {
        return static::get('view');
    }

    final public static Edit()
    {
        return static::get('edit');
    }

    // воспринимается как вариант значения
    final public static equals(Action $action)
    {
        return $this->id() === $action->id();
    }
}

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


Также можно добавить методы необходимые для бизнес логики и человеческое описание для вариантов значения для вывода на frontend. В случае использования подхода с рефлексией этого сделать нельзя.

Форкнул репозиторий и открыл на GitHub Pages. Протестировал через curl в Chrome и Firefox на Windows. Результат, мягко говоря, ошеломляет.


В Chrome все доходит как и должно и уведомление отображается. В Firefox уведомление тоже доходит, но не отображается. Отрабатывает метод messaging.onMessage() на странице и печатает тело уведомления в блоке #messages. Через fetch я получил тот же результат. В Chrome этот метод не отрабатывает.


Получается в Firefox нужно использовать метод messaging.onMessage() и в нем реализовывать показ уведомления вручную. Поскольку этот метод реализован на странице, а не в Service Worker, то мы сталкиваемся с рядом проблем:


  • Нельзя получить уведомление если сайт не открыт в данный момент;
  • Нельзя получить уведомление при закрытом браузере;
  • Если сайт открыт в нескольких вкладках, то скрипт отрабатывает во всех вкладках.

Это лишь результаты беглого осмотра. Возможно я что-то упустил. У вас другие результаты?


И спасибо за ссылку. Добавил в статью.


PS: Странно то что у меня и без messaging.onMessage() в Firefox уведомления иногда отображались.

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность