Intereting Posts
Почему массив PHP изменяется, когда его элемент привязан к ссылке? Не удается открыть удаленный файл XML с помощью функции fopen (). Какое все разрешение нужно установить на сервере или какие параметры мне нужно установить в функции fopen (). Каков наилучший способ удаления знаков препинания, символов, диакритических знаков, специальных символов? Как использовать PHP для получения всех имен файлов изображений, кроме содержащихся определенных слов? как получить текст из файла pdf и сохранить его в DB Глобальная переменная PHP, не найденная в функциях Многомерные массивы, проверьте разницу Встроенные языки скриптов для PHP? Помогите исправить код php / api / curl, пожалуйста Вопрос безопасности Codeigniter / PHP Проблемы с OpenSSL на PHP – различное поведение для разных версий Представление формы без обновления страницы Почему возникает эта ошибка PHP: «Строгие стандарты: mysqli :: next_result (): следующего набора результатов нет».? Могу ли я использовать MS SQL Server в качестве базы данных поддержки для Joomla? Результаты умножения функции в PHP

Инъекционная инъекция с помощью гидратора Doctrine 2

Я создаю специальный гидратор в Doctrine 2 в проекте Symfony 2, но для того, чтобы он выполнял то, что ему нужно, ему нужна еще одна услуга. Документация для пользовательских гидраторов показывает только, как обеспечить класс гидратора, поэтому нет возможности вводить зависимости.

Например:

$em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator'); 

Я подозреваю, что Doctrine инициализирует сами гидраторы, и поэтому любые зависимости должны будут проходить через некоторые другие классы Doctrine.

Есть ли способ предоставить пользовательскую «фабрику гидратации» или аналогичную доктрине, которая позволила бы впрыскивать дополнительные зависимости? Пользовательские гидранты кажутся довольно ограниченными без этой возможности.


Ответ: Спасибо Денису V

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

SRC / Acme / ExampleBundle / ресурсы / конфигурации / services.yml

 services: doctrine.orm.entity_manager.abstract: class: Acme\ExampleBundle\Entity\DoctrineEntityManager factory_class: Acme\ExampleBundle\Entity\DoctrineEntityManager factory_method: create abstract: true calls: - [ setMyDependency, [@acme.my_custom_service]] 

SRC / Acme / ExampleBundle / Entity / DoctrineEntityManager.php

 namespace Acme\ExampleBundle\Entity; use Acme\ExampleBundle\Hydrator\MyHydrator; use Doctrine\Common\EventManager; use Doctrine\DBAL\Connection; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager as BaseEntityManager; use Doctrine\ORM\ORMException; use Doctrine\ORM\Query; class DoctrineEntityManager extends BaseEntityManager { protected $myDependency; /** * Note: This must be redefined as Doctrine's own entity manager has its own class name hardcoded in. */ public static function create($conn, Configuration $config, EventManager $eventManager = null) { if (!$config->getMetadataDriverImpl()) { throw ORMException::missingMappingDriverImpl(); } switch (true) { case (is_array($conn)): $conn = \Doctrine\DBAL\DriverManager::getConnection( $conn, $config, ($eventManager ?: new EventManager()) ); break; case ($conn instanceof Connection): if ($eventManager !== null && $conn->getEventManager() !== $eventManager) { throw ORMException::mismatchedEventManager(); } break; default: throw new \InvalidArgumentException("Invalid argument: " . $conn); } return new self($conn, $config, $conn->getEventManager()); } public function setMyDependency($myCustomService) { $this->myDependency = $myCustomService; } public function newHydrator($hydrationMode) { if ($hydrationMode == 'MyHydrationMode') { return new MyHydrator($this, $this->myDependency); } return parent::newHydrator($hydrationMode); } } 

SRC / Acme / ExampleBundle / Hydrator / MyHydrator.php

 namespace Acme\ExampleBundle\Hydrator; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Internal\Hydration\ObjectHydrator; class MyHydrator extends ObjectHydrator { protected $myDependency; public __construct(EntityManager $em, $myDependency) { parent::__construct($em); $this->myDependency = $myDependency; } protected function hydrateAllData() { /* hydration stuff with my dependency here */ } } 

Попробуйте добавить это в свой config.yml

 doctrine: orm: hydrators: CustomHydrator: MyProject\Hydrators\CustomHydrator 

ОБНОВИТЬ

Поскольку вы не можете ничего вводить самому Hydrator, вы можете вместо этого создать собственный EntityManager (который вы сами предложили).

Это можно сделать так:

 services: name_of_your_custom_manager: class: %doctrine.orm.entity_manager.class% factory_service: doctrine factory_method: getManager arguments: ["name_of_your_custom_manager"] calls: - [ setCustomDependency, ["@acme_bundle.custom_dependency"] ] 

На самом деле хороший ответ, но, пожалуйста, имейте в виду, что сторонники Doctrine явно заявили, что не продлевают Doctrine \ ORM \ EntityManager, и я полагаю, что в будущем они сделают это окончательным, чтобы обеспечить соблюдение этого.

Таким образом, вместо предлагаемого решения, не нарушающего правила, это более чистое решение:

 <?php declare(strict_types=1); namespace App\Doctrine\ORM; use Doctrine\Common\EventManager; use Doctrine\DBAL\Connection; use Doctrine\ORM\Configuration; use Doctrine\ORM\Decorator\EntityManagerDecorator; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\ORMException; class EntityManager extends EntityManagerDecorator { public function __construct(EntityManagerInterface $wrapped) { parent::__construct($wrapped); } public static function create($conn, Configuration $config, EventManager $eventManager = null) { if ( ! $config->getMetadataDriverImpl()) { throw ORMException::missingMappingDriverImpl(); } switch (true) { case (is_array($conn)): $conn = \Doctrine\DBAL\DriverManager::getConnection( $conn, $config, ($eventManager ?: new EventManager()) ); break; case ($conn instanceof Connection): if ($eventManager !== null && $conn->getEventManager() !== $eventManager) { throw ORMException::mismatchedEventManager(); } break; default: throw new \InvalidArgumentException("Invalid argument: " . $conn); } return new EntityManager($conn, $config, $conn->getEventManager()); } } 

И теперь определите эту службу в файле services.xml как украшение желаемого менеджера сущностей:

 <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <defaults autowire="true" autoconfigure="true" public="false" /> <service id="decorated.doctrine.orm.default_entity_manager" class="App\Doctrine\ORM\EntityManager" decorates="doctrine.orm.default_entity_manager" > <argument type="service" id="decorated.doctrine.orm.default_entity_manager.inner" /> </service> </services> </container>