Ответы пользователя по тегу Symfony
  • Как symfony загружает классы через входные данные?

    @Flying
    Этому посвящена добрая часть документации компонента Dependency Injection и Service Container'а, который является центральной частью этого компонента.

    Если совсем вкратце - то вы либо описываете сервисы вручную через конфигурацию (есть несколько поддерживаемых форматов, включая аннотации, хотя они вроде реализуются внешним пакетом) либо используете преимущества autowiring'а, предоставляя Symfony всё описать за вас (с помощью compiler pass'ов, если потребуется). Собственно основная "магия" преобразования всех источников данных в кучу компилированного PHP находится как раз в compiler pass'ах, их много и можно писать свои.

    Поскольку у вас в примере - controller's action - то здесь вся магия реализуется через обработку тега controller.service_arguments, который по-умолчанию добавляется ко всем контроллерам в конфиге сервисов.
    Ответ написан
    5 комментариев
  • Doctrine как разрешить состояние гонки?

    @Flying
    По сути в вашем случае запись в базу данных является критической секцией. Соответственно вам необходима реализация любого из способов синхронизации потоков для избегания состояния гонки. Вариантов множество, но конкретно в Symfony именно для этого (и для других подобных сценариев) существует компонент Lock, он предоставляет реализации готовых примитивов синхронизации.

    Вот здесь можно посмотреть на практически готовый пример того как должен выглядеть ваш код коммита изменений с учётом использования lock'а.
    Ответ написан
    1 комментарий
  • Как правильно конфигурировать сторонний бандл в своём?

    @Flying
    Переопределение конфигурации в Symfony вне основного процесса загрузки конфигурационных файлов - не самое простое дело. Этот процесс закрыт от прямой кастомизации т.к. основной процесс загрузки и обработки конфигурации bundles целиком отдан на откуп им самим. Причина подобных ограничений в том что загрузка конфигурации - один из самых ранних этапов работы и, как и для всех подобных частей кода - там довольно мало пространства для манёвров. В связи с этим путь (и сама возможность) переопределения конфигурации будет очень сильно зависеть от того что же именно вы хотите переопределить.

    Для того чтобы лучше понять как это происходит - вам стоит подробнее изучить вопрос того как именно организована загрузка и обработка конфигурации в Symfony.

    Если вкратце:
    1. В процессе конфигурации контейнера происходит сбор данных конфигурации из конфигурационных файлов. Эти данные сохраняются в container'е через ContainerBuilder::loadFromExtension().
    2. Далее, собранные данные передаются в качестве основы в bundle extension (через метод load()). То, как именно bundle extension будет работать с собранными данными - целиком зависит от кода bundle'а, так что в целом с ними может произойти всё что угодно.

    Как вы, надеюсь, понимаете - из-за п.2 какого-то общего подхода к переопределению данных в Symfony не существует. Поэтому, как я уже писал выше, вам необходимо определиться с тем что именно вы хотите переопределить, а дальше смотреть на код загрузчика соответствующего bundle (вот он для LiipImagineBundle).

    Как видно - в случае LiipImagineBundle в целом ничего страшного не происходит, полученная конфигурация сразу отправляется в processing и потом используется для регистрации сервисов и параметров.

    Поскольку процесс сборки контейнера начинается с merge pass, то вы не можете вмешаться в этот процесс через compiler pass, как это делается обычно, однако вы можете воспользоваться вот этим куском логики для того чтобы добиться своей цели: вам достаточно определить в своём bundle собственный extension и отметить что он реализует PrependExtensionInterface. Это позволит вашему extension получить экземпляр ContainerBuilder до того как будут загружаться остальные extensions, именно это позволит вам воспользоваться ContainerBuilder::loadFromExtension() для добавления параметров конфигурации к нужному вам bundle.

    Несколько нетривиально, но должно работать :)
    Ответ написан
  • Symfony 4 - {{ app.request.getSchemeAndHttpHost() }} выдает http при https?

    @Flying
    Если в посмотрите в исходный код, то увидите что Request::getScheme(), которую использует Request::getSchemeAndHttpHost() вернёт вам https в зависимости от того признан ли запрос безопасным или нет методом Request::isSecure().

    Сам метод isSecure(), как видно по коду, возвращает true в двух случаях:
    1. Либо это HTTPS запрос и есть соответствующий заголовок
    2. Либо это запрос от доверенного proxy сервера и сервер передаёт информацию о том что оригинальный запрос безопасен


    Таким образом я бы предположил что у вас используется схема nginx + php-fpm и либо nginx некорректно сконфигурирован и не передаёт нужные данные либо nginx не указан в качестве trusted proxy.
    Ответ написан
    Комментировать
  • Обновление php приложения на symfony?

    @Flying
    С точки зрения Symfony консольная команда - это просто класс, наследуемый от Symfony\Component\Console\Command\Command. Любая консольная команда - это просто запуск класса Symfony\Bundle\FrameworkBundle\Console\Application, как можно видеть в файле bin/console.

    Таким образом ничто не мешает вам "запустить консольную команду" просто создав Console\Application и запустив нужную команду в нём, сформировав правильные входные параметры.

    Изменение структуры базы данных зависит от того как именно вы ею управляете. Используете ли Doctrine или что-то ещё? Используете ли Doctrine Migrations или нет? Без этой информации дать точный ответ нельзя. Скорее всего в вашем случае было бы логичнее всего использовать Doctrine Migrations, они ведь именно для этого и созданы.
    Ответ написан
  • Symfony - как поместить в контейнер свою реализацию сервиса?

    @Flying
    Здесь есть несколько путей:
    1. Если это что-то простое и вы работаете с Symfony Framework (т.е. не со standalone контейнером) - то вам просто необходимо описать ваш сервис в конфигурации сервисов (в Symfony 4 и выше это config/services.yaml). Как это делается - описано в документации. Описание стандартного controller_resolver можно увидеть здесь, в Yaml это будет выглядеть вот так:

      services:
        controller_resolver:
          class: Full\Name\Of\Your\Implementation
          arguments:
           - '@service_container'
           - '@?logger'
         tags: 
           - {'name:':'monolog.logger', channel: 'request'}

      ваша реализация, конечно, может отличаться по зависимостям.

    2. Если это что-то более сложное - то настройка сервисов производится через compiler pass. В них вы имеете полный доступ к ContainerBuilder и можете программно сформировать в нём всё что вам необходимо. Однако сомнительно что в данном случае вам это потребуется.


    В целом все эти вопросы очень подробно разобраны в документации компонента Dependency Injection.
    Ответ написан
    Комментировать
  • Opensource CMS на symfony?

    @Flying
    Ответ написан
    Комментировать
  • Symfony 3 - 5, Doctrine 2. Возможно ли используя Criteria выбрать данные из связанных таблиц одним запросом?

    @Flying
    Criteria - это просто возможность сформировать какое-то относительно сложное условие для QueryBuilder, не более того.

    Вам необходимо определиться с тем что именно вы хотите сделать:
    • Если вы хотите выбрать данные из связанных таблиц - то это можно сделать через QueryBuilder с гидрацией, к примеру, в массив. В этом случае запрос будет ровно один - тот что вы запускаете
    • Если вы хотите выбрать entities - то логика этих выборок определяется UnitOfWork и в общем может как приводить к 10 запросам так и не приводить в зависимости от содержимого identity map. Т.е., условно говоря, если бы связанные entities уже были бы в identity map - повторной выборки бы не происходило. Также выборки бы не происходило если бы вы обращались к identity полю связанной entity. Однако вы запрашиваете данные из связанной entity, причём делаете это раздельно для каждого entity, почему же вы ожидаете что Doctrine не полезет в базу за этими данными?
    Ответ написан
  • Есть ли аналог laravel's GlobalScope у doctrine или symfony?

    @Flying
    Я на Laravel не писал, но судя по документации это какой-то аналог дополнительного фильтра который можно навесить на запрос. Если я прав, то ближайший аналог - фильтры.
    Ответ написан
    Комментировать
  • Symfony 4 autowiring и наследование?

    @Flying
    Поскольку вы наследуете свой класс от абстрактного класса - иницализация parent'а - ваша прямая обязанность (см. сноску после первого абзаца). Таким образом, если абстрактный класс принимает свои зависимости через конструктор - вам необходимо принимать их же и передавать выше по иерархии наследования.

    Т.е. если абстрактный класс выглядит как:
    abstract class AbstractExample 
    {
      public function __construct(Foo $foo, Bar $bar) 
      {
      }
    }

    а вам необходима ещё дополнительная зависимость Baz $baz, то ваш конструктор должен выглядеть примерно так:
    class MyExample extends AbstractExample 
    {
      public function __construct(Foo $foo, Bar $bar, Baz $baz) 
      {
        parent::__construct($foo, $bar);
        // ... и далее ваша логика ...
      }
    }
    Ответ написан
    Комментировать
  • Каким способом можно сделать PARSER в Symfony?

    @Flying
    Парсинг больших файлов осуществляется в потоковом режиме. Для XML существует стандарт потокового парсинга - SAX. В PHP есть стандартный модуль, реализующий SAX через libxml2.

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

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

    Также хочу заметить что парсинг 200мб XML - не та задача которая требует отображения прогресса т.к. сам процесс парсинга будет занимать максимум единицы секунд, а скорее ещё быстрее. Больше времени может уйти на загрузку этого файла, или сохранение / обработку данных, полученных из XML, возможно вы это имели в виду?
    Ответ написан
    4 комментария
  • Как запретить одновременный вход в один аккаунт на сайте?

    @Flying
    В целом это может быть не такой хорошей идеей как кажется. Наличие нескольких одновременных сессий с разных устройств сейчас - это весьма распространённая практика, особенно если вспомнить о наличии смартфонов. Привязка к IP адресу того же смартфона жителя мегаполиса, перемещающегося в метро и переключающегося между разными WiFi сетями - тоже не вариант. Поэтому прежде чем приступать к реализации - стоит продумать этот вопрос более внимательно.

    С технической же точки зрения здесь нет ничего сложного. Поскольку под "входом на сайт", очевидно, подразумевается успешная аутентификация пользователя, а данные этой аутентификации как правило находятся в сессии (пока, для простоты, исключим варианты аутентификации по токену и т.п. вещи, не включающие в себя сессию). В этом случае задача запрета множественных входов очевидным образом сводится к тому чтобы:
    1. либо, как вы сами предложили, генерировать некий токен и сохранять его в сессии
    2. либо в качестве такого токена использовать сам идентификатор актуальной сессии пользователя

    В любом случае в каком-либо хранилище нужно будет сохранить пару "user id => token" и при дальнейших запросах мы просто проверять имеющийся у нас токен с сохранённым. В случае несовпадения принудительно делать logout с выдачей сообщения через flash messenger.
    Ответ написан
    Комментировать
  • Symfony, как безопасно хранить API ключи?

    @Flying
    В Symfony 4.4 будет добавлена возможность безопасного хранения ключей, подробнее в анонсе.
    Ответ написан
    6 комментариев
  • Упрощение стека проекта?

    @Flying
    Для работы с Elasticsearch очень хорошо работает ruflin/elastica, хотя есть и более низкоуровневые официальные binding'и: elasticsearch/elasticsearch

    Для работы с Redis чаще всего используется predis/predis, но с ним сейчас непонятная ситуация из-за того что автор уже давно не поддерживает библиотеку и сейчас есть проблемы с PHP7.3+. Есть форк исправляющий эту проблему, но большинство библиотек завязаны на predis, так что как разрулится ситуация дальше - пока не очень понятно.

    Для работы с HTTP запросами сейчас как правило используют guzzlehttp/guzzle, хотя есть и другие хорошие варианты.

    Для работы с SQL есть множество библиотек разной степени развития и популярности. Если хочется именно plain sql - то можно посмотреть на doctrine/dbal, он очень развит и стабилен.

    Связать всё это в кучу может любой современный framework, лично я бы смотрел в сторону Symfony (из 4-й версии вполне можно сделать micro framework из-за чего прекратили разработку Silex), но есть и реальные микрофреймворки, к примеру весьма популярен slim/slim
    Ответ написан
  • Имеет ли смысл начать изучение Symfony если более-менее знаком с Laravel?

    @Flying
    Вам стоит начать воспринимать ваше отношение к документации Laravel и Symfony как индикатор того что вам есть ещё что изучать и в чём разбираться. Это нормальное развитие разработчика.

    Честно говоря пока что ваши реплики не очень хорошо связуются между собой. "В общих чертах знаком", "не понимаю всего этого ООП", но при этом "могу написать на Laravel магазин какой" - это для меня звучит очень странно. Я работаю с Symfony уже порядка 5 лет, но никак не могу сказать что влёгкую напишу на ней магазин. Вот здесь команда Sylius магазин на Symfony пишет аж с 2012-го года, до релиза 1.0 добрались через 5 лет, для меня это хороший показатель. Вы точно уверены в отсутствии у вас эффекта Даннинга-Крюгера?

    Уверен, что познакомившись с ООП не только с практической, но и с теоретической стороны (возьмите хоть ту же Википедию для начала и далее по ссылкам, заодно и про другие парадигмы узнаете) вы начнёте лучше понимать и зачем оно нужно, какие проблемы и как призвано решить и т.д.

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

    Ответ получился чуть в сторону, так что back to topic: знакомиться с Symfony однозначно стоит, но не в качестве спасения от непонятной документации Laravel (там, как правильно написал DevMan её ещё меньше и она ещё сложнее), а для изучения того как на PHP можно писать действительно качественный, стабильный и поддерживаемый код. Фактически знакомиться с Symfony лучше даже не столько через чтение документации, а через изучение её исходников с отладчиком. Несколько недель подобных путешествий (с параллельным поиском ответов на вопросы "что тут вообще происходит?!") дадут вам очень много в плане развития, рекомендую :)
    Ответ написан
  • Есть ли бандл для Symfony на подобие DoctrineAuditBundle, но с возможностью формирования более расширенного человекочитаемого текста изменений?

    @Flying
    Это довольно просто делается через Doctrine lifecycle events. Вешаете обработчики на preUpdate, pretPersist, prePremove, собираете из переданных вам событий информацию для формирования нужного вам лога, затем в postFlush из собранной информации формируете запись в лог и записываете.
    Ответ написан
    Комментировать
  • Как правильно реализовать теги в Symfony?

    @Flying
    п.п.3 и 4 реализуются довольно просто через lifecycle events в Doctrine. Просто на preRemove вешаете обработчик, в нём проверяете тип entity и, если это что-то подходящее (статья или тег) то проверяете связи удаляемой entity и по необходимости подчищаете.
    Ответ написан
    5 комментариев
  • Как изменить URL в Symfony?

    @Flying
    Предположу что вы используете nginx в качестве веб-сервера в рамках Open Server.

    Если это так в этом случае public/.htaccess файл который реализует rewriting не срабатывает. Вам необходимо донастроить nginx для того чтобы он занимался преобразованием ссылок. Пример конфига есть в официальной документации.
    Ответ написан
    2 комментария
  • Symfony как правильно хранить множественное свойство?

    @Flying
    В целом, если вам не надо получать доступ к этим элементам отдельно на уровне базы данных (т.е. не надо, к примеру, выбирать только один из телефонов в запросе) то можно использовать массив и использовать тип array или json_array для mapping'а. Полный список типов можно посмотреть в документации Doctrine.
    Ответ написан
    Комментировать
  • Как написать на Symfony EventSubscriber который бы перехватывал запись в бд?

    @Flying
    Конечно можно, просто нужно использовать не Symfony event listener, а Doctrine event listener, там есть всё необходимое.
    Ответ написан
    Комментировать