• Почему шрифт в firefox отображается не правильно?

    @Flying
    А откуда взят сам файл шрифта? Какие-либо стили, регулирующие сглаживание - используются? Что за платформа, на которой запущен браузер?
    Написано
  • Систематизация фотографий и сканов на компьютере?

    @Flying
    dedarmoz, Вы правы. Есть плагин, который добавляет поддержку, но я его не пробовал, так что не скажу насколько он хорошо работает.
    Написано
  • Валидация ValueObject поля?

    @Flying
    BonBon Slick,
    Про ClassHelpersTrait понятно, замечу только что там есть относительно тонкая потенциальная ошибка в isPropertyExists() - у вас там неявно ожидается string|object, но явно проверяется только string из предположения что если не string - то object. Поскольку явно тип нигде не описан - ничто не мешает передать туда, к примеру, array и словить runtime error.

    Про DI - никто не мешает вам определить alias в config/services.yaml. Но в целом он вставляется и напрямую.

    Несколько EntityManager нужны, если приложение работает с несколькими базами данных. У меня на практике была минимум пара проектов, где была такая ситуация. Банальный пример - внешняя база пользователей из-за каких-то особенностей инфраструктуры.

    Если IAggregateRoot - интерфейс, то использовать is_a() смысла нет, я специально написал что это только для случая, если сравнение идёт с instantiable.

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

    Заметьте, что в "финальном коде" у вас осталась смесь ManagerRegistry $entityManager и из-за этого полезли ошибки типов далее по коду. Вероятно это было поправлено позже, но опубликовано именно так.

    Извиняюсь если что-то пропустил, очень много работы в последнее время...
    Написано
  • В чём смысл ContainerExceptionInterface в PSR-11?

    @Flying
    Дмитрий, На самом деле практических сценариев очень много, но их общая суть в том, чтобы знать, что множество разрозренных классов объединяет что-то общее и что именно общее у них есть.

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

    Вопрос: какой exception вы будете ловить?

    • Перечислять все, о которых вы в курсе? А если добавят ещё?
    • Ловить \Throwable? А если вам нужно разделить exception логики контейнера и, к примеру, его хранилища, являющегося внешним механизмом?


    Именно здесь и приходит на помощь интерфейс: вы просто ловите исключение по общему интерфейсу и можете быть уверены что:
    1. поймаете любое нужное, даже если оно будет определено в какой-то будущей версии
    2. не поймаете ничего, что вам не нужно
    3. ваш код будет работать без изменений, даже если вы смените реализацию контейнера на другую (ведь PSR нам нужны для interoperability)


    К примеру, посмотрите на структуру исключений контейнера в Symfony, там как раз хорошо видно то, что я описываю.
    Написано
  • В чём смысл ContainerExceptionInterface в PSR-11?

    @Flying
    Дмитрий, Нет, назначение интерфейса - определение контракта, он не обязан содержать дополнительную информацию о методах. Пустой интерфейс определяет тип, а также, возможно, его иерархию (через extends). При этом вам открывается возможность использовать все функции языка, связанные с типами: указание типов свойств, аргументов, возвращаемых значений, использование instanceof и т.п. Все они ничего не говорят о содержимом типа, только о самом типе.
    Написано
  • Как поженить php8 и apache24?

    @Flying
    Артём Варламов, вам уже в ответе перевели: "Не найден указанный модуль", но почему вы это сами не прочитали? Из этого прямо следует что Apache не может найти эту DLL по указанному пути. Остаётся проверить где она реально находится и поправить.
    Написано
  • Как поженить php8 и apache24?

    @Flying
    rPman а что такого в настройке Apache и PHP под Windows что отличало бы этот процесс от настройки их же под Linux?
    Написано
  • Как поженить php8 и apache24?

    @Flying
    Артём Варламов, из вашего же вопроса:
    httpd.exe: Syntax error on line 540 of C:/Users/Artem/Documents/Server/bin/Apache24/conf/httpd.conf: Cannot load C:/Users/Artem/Documents/Server/bin/php/php8apache2_4.dll into server: \xcd\xe5 \xed\xe0\xe9\xe4\xe5\xed \xf3\xea\xe0\xe7\xe0\xed\xed\xfb\xe9 \xec\xee\xe4\xf3\xeb\xfc.

    вот эти \xcd\xe5 \xed\xe0\xe9\xe4\xe5\xed - это что, вы прочитали?
    Написано
  • Как поженить php8 и apache24?

    @Flying
    Артём Варламов, А что в тексте ошибки-то написано?
    Написано
  • TailwindCSS — не вредит ли такое количество тегов в HTML оптимизации сайта?

    @Flying
    Ещё более сложные селекторы идут лесом при таком подходе либо же получается, что часть стилей в CSS, а часть - в HTML, да ещё и неявно.
    Написано
  • Как сделать EXISTS в репозитории?

    @Flying
    MasterCopipaster, Всегда пожалуйста :)
    Написано
  • Валидация ValueObject поля?

    @Flying
    Просмотрел, ниже несколько комментариев:

    Методы вида isMethodExists и isPropertyExists находятся в ClassHelpersTrait? Просто это ваш собственный класс и его код не приведён, так что лучше уточнить. Не очень понятно что именно эти методы делают. Если предположить что они кидают Exception в случае если тест не выполняется - то лучше их переименовать в assertMethodExists т.к. от isser'а ожидается получение boolean значения.

    Если хочется прям общего решения - то лучше передавать в качестве зависимости не EntityManagerInterface, а \Symfony\Bridge\Doctrine\ManagerRegistry, чтобы покрыть вариант когда в приложении несколько entity managers.

    У buildRepositoryFilter не указан тип возвращемого значения, хотя это явно возможно с точки зрения используемого уровня языка. В этом случае вам не надо будет смешивать в кучу проверки разных переменных в одном выражении, где вы кидаете WrongInstanceOfClassException т.к. первая проверка уйдёт автоматически (а exception можно будет кидать прямо внутри метода), а вторая и третья переместятся выше. Вторую, кстати, можно заменить на typed property, а в третьей использовать is_a() если вдруг IAggregateRoot - это instantiable, хотя и не похоже, скорее всего это интерфейс.

    Вот эту часть:
    if (null === $entity || false === is_subclass_of($entity, IAggregateRoot::class)) {
      $this->context->buildViolation('not.found')->addViolation();
      throw new WrongInstanceOfClassException();
    }

    явно надо бить на две, ведь buildViolation cтрого соответствует только первому условию, а исключение - строго второму. Иначе получается что для найденной entity неправильного типа (т.е. из-за ошибки в коде) вы кидаете публичный violation для клиента. Опять же, если только в вашем репозитории не происходит что-то действительно странное - то вы ранее проверяете соответствие типа $className, а репозиторий получаете из него, так что по-идее если второе условие вообще когда-то выполнится - значит ваш репозиторий возвращает не тот entity, для которого он предназначен. Ситуация не невозможная, но странная.

    Условие:
    if (true === $this->isPropertyExists($valueObject, $valueObjectFieldAccessName, false)) {
    
    }

    заставляет предположить что 3-й аргумент подавляет бросание исключения. Я бы разделил эти методы на isser и assert чтобы не путаться в логике. Внутри assert может вызывать isser и кидать исключение, если условие не выполнено.

    Мелочь, но в условиях вида:
    if (true === $applyConstraint instanceof AbstractComparison) {
    }

    необязательно писать true === или false ===, поскольку правая часть уже boolean и её значение равно результату сравнения. Это же касается и других выражений, сразу дающих boolean.

    Выражение:
    if (0 < $errors->count()) {
    
    }

    выглядит непривычно, но это вопрос нотации, так что если в вашем проекте так принято - не проблема.

    Если buildRepositoryFilter() общий - то он должен быть protected, а не private.

    Более подробно в логику не углублялся т.к. видна только часть кода, надеюсь написанное выше будет полезно.
    Написано
  • Как сделать EXISTS в репозитории?

    @Flying
    А зачем вам EXISTS? Это выражение нужно для подзапросов, в результате там подзапрос и будет, а зачем он вам? Запускайте прямо ваш запрос и используйте Query#getSingleScalarResult(). Если вернулся id - запись есть, если будет выкинуто NoResultException - то записи нет.

    Если на полях в where стоят индексы и сами индексы правильно построены - то там вообще запроса в саму таблицу не будет, только в индекс.

    count() как агрегат, будет конечно медленнее, но вряд ли на таком запросе, сомнительно что у вас по этим условиям хотя бы сотни результатов найдутся.
    Написано
  • Как ограничить очередь на выполнение только 200 задач в час?

    @Flying
    Максим, Обижаться на комментарии в интернете - довольно странное дело.

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

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

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

    Ну а без понимания вообще можно при любых условиях нажить себе проблем. Сколько уже на хабре было статей вида "как мы потеряли NNNNN$ за полчаса"....
    Написано
  • Как ограничить очередь на выполнение только 200 задач в час?

    @Flying
    Максим, Повторюсь ещё раз что я с вами полностью согласен :)

    Мой комментарий был исключительно о том, что использованное в вашем ответе выражение "никогда не дойдут до пользователя" в общем случае неверно (хотя и возможно в частных случаях) и может ввести в заблуждение читателей.
    Написано
  • Как ограничить очередь на выполнение только 200 задач в час?

    @Flying
    Максим, Пожалуйста обратите внимание, что в вашем ответе почему-то указано, что человек никогда не получит уведомление при наличии лимита. Но это ведь, очевидным образом, не так, поскольку лимит не на общее количество сообщений, а на скорость их отправки. Другими словами, если в час будет сгенерировано 300 уведомлений, то 200 будут отправлены в первый час, а 100 - во второй, но отправлены будут все 300. Да, в итоге часть уведомлений будет идти с задержкой, но это не означает недоставляемости в принципе.

    Хотя, как я указал в своём ответе, я согласен с вашим ответом, однако этот момент предложил бы поправить, поскольку "позже" и "никогда" - это, всё-таки, разные вещи.
    Написано
  • Что ему надо ещё?

    @Flying
    alcoholivanov, А одно другому мешает? :) Вообще прогулки с отладчиком по коду фреймворка дают массу ответов на вопросы, очень рекомендую.
    Написано
  • Что ему надо ещё?

    @Flying
    alcoholivanov, Тем не менее в исходниках Symfony видно, что причина появления этого сообщения - отключенное расширение intl.

    Если есть отладчик (а как без него) - ставьте в этом месте точку останова и смотрите на реальную ситуацию.
    Написано
  • Что ему надо ещё?

    @Flying
    А вы уверены что именно этот конфиг используется в реальности? Банально, phpinfo() показывает это расширение?
    Написано
  • Почему не работает getenv в Symfony 5.2?

    @Flying
    Телепаты в отпуске... Пример неработающего кода будет?
    Написано