Что тебе нужно знать
Doctrine 2 — это реализация шаблона Data Mapper, которая не вынуждает ваши классы модели расширять Active Record или содержать подробные сведения о реляционной модели, такие как внешние ключи.
Доктрина 2 разделена на три пакета, каждый из которых основан на предыдущем:
- Doctrine \ Common содержит многократно используемый код, такой как анализатор аннотаций и система событий.
- Doctrine \ DBAL привлекает не только конкретный драйвер базы данных, как это делает PDO, но также и диалекты SQL различных СУБД.
- Doctrine \ ORM отображает ваши графы объектов в базу данных и наоборот. Здесь происходит веселье.
Обратите внимание, что вам нужно будет запустить ваше приложение PHP 5.3 для Doctrine 2, в основном из-за использования в нем пространств имен.
Портирование картографической информации
В Doctrine 2 вам нужно будет поддерживать классы PHP вместо схемы отображения. Эти классы должны быть аннотированы @Entity и различными другими аннотациями, чтобы определить, какие столбцы и отношения должны быть отражены в базе данных. Это означает, что частные свойства, содержащие другие объекты или значения полей, должны быть явно определены. Вы можете взглянуть на пространство имен Doctrine \ Tests на github, чтобы увидеть некоторые примеры определения модели вместе с метаданными.
Таким образом, ваши классы доменной модели управляются вами, и вы должны поддерживать согласованность графов объектов. Затем информация сопоставления может быть прочитана Doctrine 2, чтобы перенести ваши объекты в таблицы базы данных и воссоздать их при выполнении запроса. Доктрина 2 гораздо больше сфокусирована на картировании, а не на проверке доставки и поведении, как это сделала Доктрина 1.
Конечно, перенос метаданных Doctrine 1 в Doctrine 2 можно автоматизировать с помощью сценария, содержащегося в инструментах командной строки Doctrine .
doctrine orm:convert-d1-schema
преобразует вашу YAML-схему в информацию отображения YAML для Doctrine 2. Однако вам все равно нужно будет сгенерировать ваши PHP-классы, только в первый раз.
Я думаю, что лучший подход к хранению картографической информации — это непосредственно исходный код класса с аннотациями, которые можно легко синхронизировать с полями, на которые они ссылаются. В то время как в других языках аннотации требуют присутствия их классов для компиляции, приложения PHP определяют аннотации как комментарии, которые игнорируются чем-либо еще, кроме Doctrine 2. Однако могут быть проблемы с APC и другими оптимизаторами, которые удаляют комментарии.
Теперь вам нужно настроить инструмент командной строки doctrine для загрузки метаданных, сгенерированных предыдущим шагом, а затем выполнить:
doctrine orm:convert-mapping annotations /path/to/folder/where/generate/classes
Отныне вы будете поддерживать метаданные только в классах в этой папке (после реконфигурации Doctrine, чтобы читать их вместо метаданных YAML). Сгенерированные классы будут пусты, кроме аннотированных частных свойств, и вам все равно придется вставлять оригинальные публичные методы, если они у вас есть.
Этот механизм портирует отношения так же, как и столбцы, но только тот, который явно определен (в ключе отношений ). Отношения, обнаруженные автоматически, наподобие тех, которые выведены из полей, похожих на field_id , не переносятся , но вы все равно будете иметь внешний ключ в виде столбца. Объекты Doctrine 2 не сохраняют внешние ключи внутри, поэтому они будут действовать как папка-заменитель, которая должна быть заменена аннотацией отношения.
Код вашего приложения
Doctrine 2 имеет более чистую архитектуру, чем предыдущая итерация, и она способствует внедрению Dependency Injection вместо статического доступа к классам Doctrine_ * или с помощью одноэлементного типа Doctrine_Manager.
Вот что нужно добавить для замены ваших старых вызовов Doctrine _ * :: * ():
- Если вы использовали Doctrine_Connection или Doctrine_Manager напрямую, теперь вы должны внедрить Doctrine \ ORM \ EntityManager, который является Фасадом Doctrine 2. Когда у вас есть ссылка на Entity Manager, вы можете получить доступ к любой функциональности Doctrine 2.
- Если вы ссылались на экземпляры Doctrine_Record , вам придется внедрять или создавать экземпляры ваших моделей, которые не расширяют базовый класс Doctrine.
- Если вы ссылались на объект Doctrine_Table (один), вы можете вместо этого внедрить Doctrine \ ORM \ EntityRepository, полученный с помощью $ em-> getRepository ($ className).
- Если вам нужен доступ к метаданным сопоставления , например, для определения типа поля, у вас есть точка входа, где доступны метаданные каждого класса: $ em-> getMetadataFactory () предоставит вам Doctrine \ ORM \ Mapping \ ClassMetadataFactory, который вы можете запросить для метаданных каждого класса, который вы знаете.
- Если вместо этого вам нужны метаданные только для одного класса , вы можете получить с помощью $ metadataFactory-> getMetadataFor ($ className) один Doctrine \ ORM \ Mapping \ ClassMetadata для внедрения в ваш собственный объект.
- Для выполнения запросов вы можете создать экземпляр Builder для запросов с помощью $ this-> em-> createQueryBuilder ($ className). Пока у вас нет QueryBuilder, он предоставляет вам свободный интерфейс для добавления частей DQL; когда вы вызываете метод getQuery (), он возвращает неизменный объект Query, который вы можете выполнить с помощью нескольких служебных методов, таких как getSingleResult ().
Стоит ли хлопот?
Doctrine 2 — это новая основная версия, и она действительно потребует некоторых изменений в вашей кодовой базе, которые займут больше часа. Тем не менее, его картографическая мощь, хорошо продуманная архитектура и скорость того стоят. Если вы хотите заняться серьезным объектно-ориентированным программированием на PHP, вам придется однажды рассмотреть Doctrine 2.