#php #doctrine-orm #doctrine
#php #doctrine-orm #доктрина
Вопрос:
Я довольно долго искал ответ на этот вопрос, и я просто не получаю ничего, что звучит разумно прямо сейчас. Итак, вот дилемма…
У меня есть Entity
каталог со структурой вложенности. Это просто работает намного лучше для нашей организации. Итак, у нас может быть что-то вроде:
./Entity
./Entity/User
./Entity/User.php
./Entity/User/Type
./Entity/User/Type/Administrator.php
./Entity/User/Type/Editor.php
Итак, в основном 2 типа пользователей. В этом случае пространство имен будет следовать за PSR4. В приведенном выше случае у нас будут следующие файлы:
User.php
namespace Entity;
use DoctrineORMMapping as ORM;
/**
* User Entity
*
* @ORMEntity
* @ORMInheritanceType("SINGLE_TABLE")
* @ORMDiscriminatorColumn(name="user_key", type="string")
* @ORMDiscriminatorMap({
* "administrator" = "EntityUserTypeAdministrator",
* "editor" = "EntityUserTypeEditor",
* })
*
* @ORMTable
*/
abstract class User
Administrator.php
namespace EntityUserType;
use DoctrineORMMapping as ORM;
use EntityUser;
/**
* Administrator Entity
*
* @ORMEntity
*/
class Administrator extends User
И при этом я получаю следующую ошибку:
DoctrineORMMappingMappingException: Entity class 'EntityUserTypeAdministrator' used in the discriminator map of class 'EntityUser' does not exist.
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php:479
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:2875
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:2847
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php:265
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php:79
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:155
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:306
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:82
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:185
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:288
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1764
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1737
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:610
Итак, как мне зарегистрировать это пространство имен или в чем здесь проблема? Я попытался явно передать путь к сущности AnnotationDriver
, который используется для сопоставления.
Я не ищу здесь решение конфигурации Symfony yml. Я также не ищу 2 экземпляра менеджера сущностей. Мне нужен один диспетчер сущностей, и я хочу, чтобы эти пространства имен поддерживались.
При создании прокси-классов я подтвердил, что они правильно распознают вложенные объекты пространства имен и правильно генерируют прокси-классы.
Обновить:
Кажется очевидным, что прокси-классы генерируются с дополнительным пространством имен, поскольку фактические сущности структурированы. Итак, я думаю, это выглядит правильно.
// Normal
namespace EntityProxy__CG__Entity;
// Nested
namespace EntityProxy__CG__EntityUserType;
Однако эти файлы прокси-классов находятся на том же уровне, что и все другие прокси-классы — вложенности нет.
Я недостаточно знаю о том, как прокси загружаются и используются в кэшировании позже, чтобы определить, является ли это проблемой или нет. Пара тестов с изменением пространства имен и вложением в каталоги в пути прокси не дали никаких положительных результатов, возможно, потому, что это все еще нарушало логику, или потому, что это не проблема, основанная на способе загрузки прокси.
Комментарии:
1. Вы говорите, что вам не нужно решение на основе Symfony, но префикс ORM происходит от Symfony. При использовании готового Doctrine вы обычно просто используете @Entity вместо @ORMEntity . Но я подозреваю, что у вас простая проблема с отображением пространства имен PSR4. Использование Entity в качестве префикса корневого пространства имен немного странно. Обычно у вас будет префикс пространства имен для всего проекта, который, в свою очередь, становится частью вашего сопоставления PSR4. Я тестирую ваш код, используя простой загрузочный файл doctrine, и он работает так, как ожидалось. Я могу опубликовать свой код в качестве ответа, если хотите.
2. Если нет, то покажите свой bootstrap.php код и раздел psr4 composer.json. Не забудьте запустить ‘composer dump-автозагрузка’ после внесения любых изменений psr4 в composer.json.
3. @Cerad спасибо за информацию. Пространство имен здесь используется только для примера, это весь псевдокод. Вы предполагаете, что то, что описано в этом выпуске, возможно и поддерживается Doctrine? Псевдоним
ORM
use просто позволяет использовать меньше инструкций use. В этом нет ничего по сути «Symfony». В Composer нет проблем с автозагрузкой. Существуют службы, расположенные в аналогичных вложенных каталогах, которые хорошо работают там и с компонентом DI Symonfy. К сожалению, начальная загрузка для менеджера сущностей довольно большая и сложная. Но, если это должно работать…4. Проблема решена. Перед именем файла был добавлен начальный (пробел). вздох
5. Рад, что у вас все получилось. Меня всегда немного смущало (для меня), что примеры в Doctrine docs редко используют ORM, в то время как Symfony используют. И если вы возьмете один из примеров Doctrine и добавите оператор use, он все равно не сработает. Вам нужно использовать определенный читатель аннотаций. Просто одна из этих вещей.