Ответы пользователя по тегу Symfony
  • Как подменить используемый EntityManager?

    @HellWalk Автор вопроса
    Не смотря на наличие документации на которую сослался Денис Дерепко, она мало помогает в задаче подменить именно EntityManager, и именно когда к нему идет обращение в зависимостях через EntityManagerInterface.

    По этому отдельным ответом пишу решение:

    config/services.yaml:
    App\Proxy\EntityManagerProxy:
        decorates: 'doctrine.orm.entity_manager'


    Proxy-обертка (здесь оставив за скобками почему в документации декоратор, а в моем случае proxy) с нужным функционалом - чтобы EntityManager переподключался в базе в случае потери соединения с базой (а доктрина закрывает соединение в случае любой SQL-ошибки):

    class EntityManagerProxy implements EntityManagerInterface
    {
        private ObjectManager $entityManager;
        private ManagerRegistry $doctrine;
    
        public function __construct(ObjectManager $entityManager, ManagerRegistry $doctrine)
        {
            $this->entityManager = $entityManager;
            $this->doctrine = $doctrine;
        }
    
        /**
         * @param $object
         * @return void
         * @throws Exception
         */
        public function persist($object): void
        {
            $this->correctionConnect();
            $this->entityManager->persist($object);
        }
    
        /**
         * @return void
         * @throws Exception
         */
        public function flush(): void
        {
            $this->correctionConnect();
            $this->entityManager->flush();
        }
    
    
        private function correctionConnect(): void
        {
            // Для ошибок когда падает сама база или соединение с ней, например:
            // SQLSTATE[57P01]: Admin shutdown: 7 FATAL:  terminating connection due to administrator command
            // SQLSTATE[08006] [7] could not translate host name "postgres" to address: Temporary failure in name resolution
            // (например, когда на время падает контейнер с postgres)
            if ($this->entityManager->getConnection()->ping() === false) {
                $this->entityManager->getConnection()->close();
                $this->entityManager->getConnection()->connect();
            }
    
            // Для ошибки "The EntityManager is closed" (например, при ошибки SQL-запроса)
            if (!$this->entityManager->isOpen()) {
                $this->doctrine->resetManager();
                $this->entityManager = $this->doctrine->getManager();
            }
        }
        
        // Все другие методы для EntityManagerInterface перебрасываются напрямую на базовый EntityManager
    Ответ написан
    Комментировать
  • Как понять, что кэш сохранился в Redis?

    @HellWalk Автор вопроса
    Все, разобрался. Ожидаемо Symfony добавляет свой хеш к ключам.

    Посмотреть с каким ключом сохранилось значение можно через вывод всех ключей:

    127.0.0.1:6379> keys *
    1) "gTPBdlcdoq:270378f0-b29c-4bf6-b7d1-7a64d6e212ff"
    Ответ написан
    Комментировать
  • Как в Doctrine, в DBAL указать PDO::ATTR_PERSISTENT => true?

    @HellWalk Автор вопроса
    Проблема с лимитом подключений к базе в тестах решилась добавлением $this->entityManager->getConnection()->close(); в tearDown()

    /**
    * @throws ConnectionException
    */
    public function tearDown(): void
    {
        parent::tearDown();
        // ...
        $this->entityManager->getConnection()->close();
    }


    Забавно, что в официальной документации (с.м. последний пример):
    https://symfony.com/doc/current/testing/database.html

    Указано:
    protected function tearDown(): void
    {
        parent::tearDown();
    
        // doing this is recommended to avoid memory leaks
        $this->entityManager->close();
        $this->entityManager = null;
    }


    Что, по факту, не помогало решить проблему с лимитом подключений.
    Ответ написан
    2 комментария
  • Возможно ли подружить Symfony + gRPC + Codeception?

    @HellWalk Автор вопроса
    В общем, все оказалось просто (когда знаешь что делать)

    Необходимо в config/services.yaml в существующую строку:
    exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}'

    добавить папку, в которой находятся gRPC-классы, в моем случае это папка src/Grpc и строчка в конфиге выглядит так:
    exclude: '../src/{DependencyInjection,Entity,Tests,Grpc,Kernel.php}'


    Спасибо за наводку по решению BoShurik
    Ответ написан
    Комментировать
  • Как обнулить или объединить миграции и оставить одну?

    @HellWalk
    Если миграции делались через
    php bin/console make:migration
    А под сохранением данных вы подразумеваете структуру таблиц, а не их содержимое, то все просто:

    1. удаляете все миграции
    2. удаляете все таблицы из базы (включая migrations)
    3. выполняете еще раз команду "php bin/console make:migration"

    P.S. На всякий случай, сделайте бекап базы и git-коммит, чтобы в случае чего откатить все назад.

    P.P.S. Можно и данные в базе сохранить - сделать нулевым пунктом бекап базы, изменить его так, чтобы в нем остались только команды на добавление данных, и накатить дамп четвертым пунктом.
    Ответ написан
    6 комментариев
  • Существует ли аналог RBAC Yii2 в Symfony?

    @HellWalk Автор вопроса
    Итак, поразбирался-покопался сам - для симфони есть Sonata - несколько больших бандлов для создания админки. В том числе там есть функционал схожий с RBAC.

    Но само решение спорное:
    1. Sonata слабо развивается, и выглядит брошенной
    2. Чем сложнее становится логика в проекте - тем меньше помогают (и начинают мешать) решения из коробки
    3. Сами разработчики Симфони рекомендуют использовать Voters

    Вот такие дела.

    P.S. Официальная документация по Sonata устарела, и по ней её не поставить. Мне помогло это руководство с хабра.
    Ответ написан
    Комментировать