Фон
Я разрабатываю приложение с использованием Symfony 2, которое структурировано таким образом, что "Core" bundle определяет сущности, отношения и поля. Затем другие узлы могут специализировать основные функции по наследованию, так называемые "дочерние" пакеты.
Аннотации Doctrine 2 были использованы для определения основного объекта, называемого "Пакет". "Пакет" связывает архитектурный дизайн и кусок земли - по сути, пакет для дома и земли. Я привел примеры к более базовой форме, поэтому вы не найдете определения для Land и ChildLand в приведенных ниже примерах, но можете предположить, что они были реализованы аналогичным образом.
Обновление
По словам пользователей на канале FreeNode #symfony, это проблема доктрины, так как команда app/console просто вызывает консоль доктрины. Я использую доктрину 2.3.
Вот диаграмма, показывающая общую ситуацию, которая вызывает проблему, которая должна помочь визуализировать сценарий:
(ссылка imgur на полноразмерное изображение)
Кроме того, здесь приведена ссылка на отчет об ошибке для трекера третирования доктрины: http://www.doctrine-project.org/jira/browse/DDC-2605
Обновление 2 - Более подробная ERD
Структура отношений между объектами была поставлена под сомнение, поэтому ниже - лучший пример структуры данных, которую мы реализуем.
Основное требование - снова иметь основные классы, которые предоставляют общий набор сущностей и полей. Ролевые классы в корпоративных пакетах расширяют эти основные классы.
Мы давно рассмотрели EAV, но в этом подходе мы потратим гораздо больше времени на создание платформы и инструментов для управления данными EAV, а не на удовлетворение существующих бизнес-требований, мы не сможем использовать доктрину для управления сущности, поскольку они будут определены в базе данных и т.д. и т.д.
По прошествии времени, и я лучше понимаю эту проблему, кажется, единственная проблема связана с геттерами и сеттерами, созданными инструментом CLI доктрины, поскольку они нарушают контракты типа hinting, как указано ниже. Эта структура отлично работает, когда эти проблемы исправляются вручную.
(ссылка imgur на полноразмерное изображение)
Создание объектов с помощью инструмента CLI
Итак, изначально я использовал инструмент командной строки...
> app/console doctrine:generate:entity
... для создания заглушек объектов с базовыми сопоставлениями полей, затем вручную добавлено отношение к земле (поскольку инструмент, похоже, не поддерживает отношения):
Это результирующий код:
core Объект пакета: http://pastebin.com/3ujPT1mJ
дочерний объект пакета: http://pastebin.com/sjAB0XJ2
Генерация Getters и Setters
Затем я создаю геттеры и сеттеры, выполняя:
> app/console doctrine:generate:entities CompanyCoreBundle
> app/console doctrine:generate:entities CompanyChildBundle
Что автоматически изменяет определения ядра и дочернего объекта:
core Объект пакета: http://pastebin.com/kfQRxcnm
дочерний объект пакета: http://pastebin.com/UdiPP9xX
Проблема!
Итак, суть проблемы такова: если вы сравниваете функцию setLand в пакете Core и Child, вы можете видеть, что объявления разные:
public function setLand(\Company\CoreBundle\Entity\Land $land = null)
public function setLand(\Company\ChildBundle\Entity\ChildLand $land = null)
Ошибки: (
К сожалению, подсказки разных типов приводят к строгим ошибкам PHP, например:
PHP Fatal error: Class 'Symfony\Component\Debug\Exception\ContextErrorException' not found in ... Company/ChildBundle/Entity/ChildPackage.php on line ...
и
Runtime Notice: Declaration of ... should be compatible with ... in ... line ...
Причина ошибок
Проведя некоторое исследование относительно того, почему это было проблемой, я читал в нескольких местах, что изменение типа намека в подклассах прерывает типы намекающих контрактов (см. этот пост: Есть ли способ переопределить подсказку типа к классу потомков при расширении абстрактного класса?).
Опции
Есть некоторые очевидные, но не идеальные варианты:
- Я могу подавить строгие уведомления довольно легко, но мой менеджер по развитию борется с перспективой создания исключений из снежинок в наших процессах CI.
- Я могу вручную отредактировать код, который генерирует доктрина, чтобы удалить все намеки типа или обеспечить, чтобы подсказки типа дочернего класса были такими же, как родительские. Выполнение этого делает работу кода, но я вижу, что это утомительно, если я не пишу некоторые сценарии, чтобы управлять этим для меня.
- Я могу просто не использовать инструменты командной строки и вручную создавать сущности и сущности. Я предпочел бы автоматизировать это со сценариями: (
Мой вопрос!!! (Наконец)
Мой вопрос в том, можно ли использовать инструменты командной строки, чтобы делать то, что я пытаюсь сделать здесь? В идеале, мне бы хотелось, чтобы вы могли выполнять команды консоли доктрины для генерации сущностей и геттеров и сеттеров без ручного вмешательства, чтобы исправить подсказки типов в подклассах. Если это не так легко достижимо, какой лучший вариант?
Благодарность
Спасибо!