Вот он какой, Doctrine 2.0 (Приурочено к релизу Doctrine 2.0 Alpha 3)

    image
    Поздравляю, коллеги! 3 дня назад увидела свет треться альфа-версия самого мощного на сегодняшний день ORM-фреймворка для PHP: Doctrine.

    И эта новость по большему счету заслуживает внимания потому что в Doctrine 2.0 произошли очень существенные изменения в сравнении с предыдущими версиями. Сразу замечу, что вкусности эти потребуют от нас ни много ни мало — поддержку php 5.3.

    Официальный тизер Doctrine 2.0 выглядит так:
    1. <?php
    2.  
    3. namespace Doctrine\Tests\Models\CMS;
    4.  
    5. /**<br/>* @DoctrineEntity(tableName="cms_articles")<br/>*/
    6. class CmsArticle
    7. {
    8.    /**<br/>    * @DoctrineId<br/>    * @DoctrineColumn(type="integer")<br/>    * @DoctrineIdGenerator("auto")<br/>    */
    9.    public $id;
    10.  
    11.    /**<br/>    * @DoctrineColumn(type="varchar", length=255)<br/>    */
    12.    public $topic;
    13.  
    14.    /**<br/>    * @DoctrineColumn(type="varchar")<br/>    */
    15.    public $text;
    16.  
    17.    /**<br/>    * @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsUser",<br/>           joinColumns={"user_id" = "id"})<br/>    */
    18.    public $user;
    19.  
    20.    /**<br/>    * @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsComment", mappedBy="article")<br/>    */
    21.    public $comments;
    22. }


    Итак, на что нам здесь следовало бы обратить здесь внимание:

    1) Мы задаем мета-данные для меппинга класса с помощью комментариев DocBlock (XML-меппиг и YAML-меппинг никуда не делся)

    2) Мы не наследуем наш класс CmsArticle от встроенных класов Doctrine.

    3.) Свойства класса не обязаны быть объявлены как public, они могут быть приватными или защищенными. Doctrine не требует от вас наличия getter'od и setter'ов для каждого свойства. Вы полностью свободны в том, как вы будете проектировать ваши классы.

    Друзья, по-моему это великолепно!

    Смею предположить, что чтение комментариев DocBlock реализовано с помощью Reflection (там есть метод getDocComment).
    Довольно интересное применение Reflection.
    Кстати, еще более активно и более элегантно(имхо) это используется в Recess php framework. Случайно наткнулся на него и был поражен, увидел там именно то, что хотел делать в собственном велосипеде. Вещь однозначно заслуживает внимания.

    Производительность:
    Doctrine 2.0 на php5.3 кушает на 31% меньше памяти и выполняется на 17% быстрее, чем Doctrine 1.0 на PHP 5.2.8
    (информация из предварительных тестов в блоге разработчиков)

    Что нового в Doctrine 2.0 Alpha 3:
    Самое существенное с моей точки зрения это функционал для конвертирования схем из Doctrine 1.0 в 2.0.
    А также более 60 фиксов, рефакторинг кода, работа над драйверами для меппинга и экспорта, как говорят разработчики, код начинает становиться стабильным.

    Чего нам ждать:
    11 декабря 2009 будет еще один альфа-релиз, а 8-го января выйдет уже первая бета.

    Ссылки:
    Здесь живет Doctrine PHP ORM
    Вот документация по версии 2.0:
    Посты из блога разработчиков с тегом 2.0

    Друзья, надеюсь вам было интересно и вы почерпнули что-то новое для себя! (лично мне очень понравилось использование комментариев DocBlock) Жду активного обсуждения!
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 72

      +5
      PHP идет по стопам Java, наступая на те же грабли.
        +2
        Да, очень положе на JPA: docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e1177

        В Groovy, Ruby, Python — есть возможности мета-программирования и там действительно можно сделать лучший API. В Java это достигается с помощью аннотаций — где там грабли-то?
          +9
          Ну так Хибернейт совсем неслабая штука.
          А о каких граблях идет речь?
          0
          Сам недавно познал разбор phpDoc'a через рефлексию…
            0
            Можно немного подробнее с чем это едят? и почему все хвалят?
            –9
            самого мощного на сегодняшний день ORM-фреймворка для PHP: Doctrine
            хорошо завернул. автор, какие еще орм-фреймворки ты знаешь?
              +4
              Propel?
                +3
                Оу, я прочел ваши мысли еще до того как вы написали этот комментарий и сразу начал писать ответ :)

                Если знаете ORM для PHP получше Doctrine — советуйте и аргументируйте, буду очень признателен, т. к. у самого манечка с пристрастием копаться в различных библиотеках в поисках наиболее архитектурно правильных и красивых решений.

                Лично мне очень нравятся идеи RedBean (вот реализацию как по мне можно было бы сделать покрасивее), хотя это не совсем ORM, и очень нравится Recess php framework (Это вообще MVC фреймворк, извиняюсь за оффтоп), но не своим ORM, я предвкушаю, что на нем получается очень высокая скорость разработки.
                А вообще мне нравится Django (RoR конечно же тоже нравится, но Django нравится больше потому что: native механизм adminpages, шаблоны проще (хотя мой идеал шаблонов далек и от джанги), нет привязки к Javascript библиотекам (ура! Да здравствует JQuery!), python популярнее и на данный момент если не ошибаюсь — быстрее (синтаксис ruby честно говоря больше нравится чем python)

                Ноооо… что-то меня понесло… в общем, вот такое у меня мировоззрение веб-разработчика, а мы сейчас говорим об ORM для PHP :)
                +1
                Вот что меня смущает — я не уверен, правильно ли говорить, что Doctrine — самый мощный PHP ORM. Возможно это субъективные впечатления, подкрепленные субъективными мнениями веб-разработчиков из близких мне Интернетов.
                Собственно для справки: Из ORM для PHP я имел дело только с Doctrine, Propel, RedBean(если это можно сюда отнести), и ORM из Kohana Framework.

                Возможно вы знаете какие-то менее популярные, но очень хорошие ORM(и близкие по идеологии) библиотеки для PHP — Welcome, делитесь! :)
                  +1
                  Что можете сказать про Propel в сравнении с Doctrine?
                    +4
                    Ничего хорошего.

                    Чтобы достать, скажем, посты + комментарии + юзеров-создателей этих постов/комментариев, в Propel нужно писать что? Праавильно, кастомный peer method. ~10LOC на класс. В Doctrine это делается в 2 leftJoin'а.
                    Кэширование запросов/resultsetов? Через одно место. В Doctrine это имеется плюс вагон backendов.
                    Вложенные behaviorы? Нет, даже близко.
                    Наследование? Нет.

                    Вроде всё.
                      0
                      Да, вот я, вроде, изучил Симфони на Propel, а потом понял что сделал глупость, и надо было доктрину осваивать… Ну, никогда не поздно меняться, поэтому начал учить Django:)
                        0
                        Вложенные behavior'ы есть в propel 1.4 (и symfony 1.4 соответственно)
                          0
                          "~10LOC на класс" а что это?
                            0
                            Вот есть у вас бложек. В блоге есть Посты, у Постов — Комменты, у тех и других — Пользователи-создатели. И нужно вывести в просмотре Поста все комменты + логин создателя и его аватарку. Без самописного Peer method будет выбирать всех владельцев по одному, что не есть кошерно, хотя иногда и приемлемо. По крайней мере, возмущения на предмет «Почему так много запросов?!» обеспечены. Значит, пишем этот метод.
                            Для начала копипастим BasePostPeer::doSelectJoinCommentAndUser в PostPeer::doSelectJoinCommentAndUserAndCommentOwner(). Затем в вышеупомянутом методе пробегаемся по извлечённым комментам, собираем их idшники, достаём юзеров, запихиваем этих юзеров в комментарии. Вот там-то и получается ~10LOC/таблицу.

                            Как-то так. Извините за неровный почерк.
                          +2
                          Могу сказать что код там менее интуитивный(имхо), структура документации тоже не тек хороша(имхо) (хотя и у Doctrine совсем не шоколад), зато ее там больше чем для Doctrine 2.0 в данный момент.
                          Возможно кому-то Propel больше понравится в этом плане, но я не отношусь к числу этих людей.
                          Так же насколько я знаю, там нет возможности задавать мета-данные для меппинга в комментариях и нет поддержки YAML (а вот XML есть и там и там).

                          Я бы сказал отличия в основном в немного разных подходах и мелочах, но в общем можно сказать что Doctrine немного богаче в плане альтернативных способов выполнить одни и те же действия.
                          –1
                          Наверное скопом можно добавить все популярные ООП фреймворки, ну, кроме symfony ;)
                            +1
                            Мне очень, очень нравится синтаксис join'ов и условий в CakePHP. Однако очень не нравится ужасная жиробасность CakePHP, поэтому пришлось самому накатать велосипед с почти таким же синтаксисом:

                            $news=$News->contain(array(
                            	'NewsComment'=>array(
                            		'User'=>array('fields'=>array('user_id', 'username')),
                            	),
                            ))->find(array(
                            	'News.id'=>$id
                            ));
                            
                              0
                              Насколько я понял из местных комментов, Doctrine позволяет делать примерно так же. Так что, вероятно, буду смотреть Doctrine, когда надоест, что в команде на двух программистов — два ORM-велосипеда.
                                0
                                Да, симпатично
                              +1
                              wiki.limb-project.com/doku.php?id=limb3:ru:packages:active_record — отличная реализация паттерна ActiveRecord на PHP есть в Limb Framework.
                                0
                                Штука хорошая, да.
                                Но Doctrine поболее будет. Вот такой штуки как DQL там нет. Ну и еще нескольких штук.
                                Но если не нужен весь монстр Doctrine, то можно пользовать.
                                  +3
                                  никогда не понимал смысла DQL. приведите пример, когда без него ну никак.
                                    0
                                    В том что язык запросов не зависит от СУБД, от конкретного маппинга (имен таблиц и полей в БД) ну и т.д., так как оперирует бизнес-объектами а не таблицами.
                                      0
                                      слишком расплывчато. можно конкретнее?
                                        +1
                                        Хм, вроде, должно быть итак понятно… DQL оперирует с нашими классами/свойствами, а не с таблицами/колонками. А потом автоматически транслируется в нужный SQL для конкретной СУБД.
                                          –1
                                          перефразирую вопрос:
                                          зачем DQL, если всё можно сделать и без его использования, с помощью «стандартных» методов выборки?
                                            +1
                                            а что есть «стандартные методы?» =)
                                              +1
                                              так нечестно :-)
                                              стандартные для меня методы — это методы/свойства классов, без написания каких бы то ни было запросов явном виде или произвольно взятом диалекте, производном от sql
                                                +1
                                                слишком расплывчато =)
                                                DQL, как и SQL, можно отнести к DSL, которые удобны именно для выборки данных.
                                                Можно пример методов выборки, которые настолько же мощны как чистый SQL?
                                                  0
                                                  я потому и спрашивал, что мне интересно, когда в _рядовых_ (а именно на эту нишу ориентированы ОРМ) проектах возникают задачи, которые невозможно решить более простыми и читабельными средствами (без (S|D)QL)
                                                    0
                                                    Ну, на счет рядовых проектов и ОРМ я с вами не согласен, но это тема для другой дискуссии.

                                                    Во-вторых, я так и не пойму, что вы считаете более простыми и читабельными средствами чем SQL, имхо, SQL как раз простой и читаемый способ.

                                                    Какие уровни абстракции обычно есть в ОРМ:
                                                    — верхний уровень работа непосредственно с объектами и их зависимостями (хорошо для организации стандартного CRUD).
                                                    — Различные билдеры для запросов (Doctrine Query Builder, Hibernate Criteria, Zend_Db_Query, Propel Criteria, etc) Это уже более мощное средство, однако все равно не так сильно как чистый SQL
                                                    — DQL/HQL уровень наиболее близкий (а соответственно наиболее функциональный) к чистому SQL.

                                                    Кроме того я не разделяю мнения что SQL/DQL/HQL менее понятны чем нативные методы, имхо, совсем наоборот. При отсутствии уровня DQL/HQL приходится использовать билдеры для абстракции от чистого sql. Хотя я лично считаю что билдеры надо использовать там где нужно именно динамически билдить запрос в зависимости от каких либо параметров (самый частый вариант — поиск по набору критериев), в стандартном же случае проще использовать DQL/HQL.
                                                      0
                                                      Складывается впечатление, что эти задачи возникают практически на ровном месте. :)
                                                      А если серьёзно — то по мере роста и усложнения проекта такие задачи возникнут практически наверняка. Я бы даже сказал, что обойтись штатными средствами Propel («читаемые средства без *QL») можно разве что на самых ранних этапах проекта.
                                                +1
                                                например, возможность использовать INDEXBY
                                                Doctrine_Query::create()
                                                ->from('User u INDEXBY u.username')
                                                ->innerJoin('u.Groups g INDEXBY g.name');
                                          0
                                          Оптимизация, кеширование…
                                            0
                                            слишком расплывчато. как DQL связан с вопросом кеширования?
                                              +2
                                              Примерно так же, как и с оптимизацией.

                                              Например, есть таблица постов (Posts), у каждого поста есть автор (Users), ну и у пользователя профиль (Profiles).

                                              Если я буду перебирать $posts хранящий посты в цикле и забирать по relation информацию о профиле, это породит множество запросов — равное count($posts)*2, насколько я понимаю.

                                              При использовании DQL, я могу сразу приджойнить нужные таблицы, и все данные заберу в один запрос.

                                              Более того, этот один запрос я смогу закэшировать, и гибко управлять временем жизни кэша конкректно по этим данным, очищать кэш в случае необходимости так же удобно. И т.д. Поправьте меня, если я где-то вру.

                                              Единственный способ делать это иначе, как я понимаю, RawSql API — но это далеко не самый удобный способ.
                                                0
                                                в коллекции есть загрузка по требованию связанных объектов
                                                www.doctrine-project.org/documentation/manual/1_2/en/component-overview#collection:loading-related-records
                                                  0
                                                  Вы про $posts->loadRelated('Users');?

                                                  Это несомненно помогает, но DQL поможет добиться большей производительности.
                                                  Опять же, как управлять временем жизни кеша при loadRelated()? Наверное, это возможно, указав общее время жизни кэша для таблицы (я правда не знаю как), но управление на уровне запросов мне кажется более надежным.

                                                  Ну а в целом — Вы правы в том, с точки зрения реализации бизнес-логики приложения, без DQL можно обойтись пожалуй всегда, ну или почти всегда.
                                                    0
                                                    Разве кеш в доктрине не сбрасывается по модификации данных?
                                                    Если да — тогда пусть срок жизни будет хоть 100лет :-)
                                                      0
                                                      Может я что-то криво делал, но по моему не сбрасывает :)

                                                      «You should always consider using a result cache if the data returned by the query does not need to be up-to-date at any time.»

                                                      Я сам дня 3 писал умный контроллер кеша, чтобы реализовать такой вот сброс. Неужели оно было напрасно? :)
                                                        0
                                                        ясненько…
                                                        но я вообще за то, что кеширование, если оно нужно на уровне слоя данных — пусть лучше делает субд.
                                                        если нужно более высокоуровневое кеширование — то и делать его нужно уже уровнем выше.
                                                        +1
                                                        к сожалению в 1.* точно не сбрасыватся :(
                                                  0
                                                  Мы случайно не путаем понятия DQL? Я говорю о Doctrine Query Language, Вы тоже? Или о Data Query Language? :)
                                              +2
                                              Честно говоря мне тоже DQL совсем не нравится
                                                0
                                                По мне, так DQL — это костыль. Хотя, может и есть ситуации, когда база часто переезжает с одного движка на другой и благодаря ему код не нужно переписывать.
                                                  0
                                                  Даже один переезд (с, скажем, MySQL на Postgres — абсолютно логично, кстати) полностью оправдывает наличие DBAL, ящитаю.
                                                    0
                                                    а вы часто с одно СУБД на другую переезжаете?
                                                      0
                                                      Я думаю достаточно одного переезда (что автор поста выше и подчеркнул), чтобы такая абстракция полностью оправдала себя.

                                                      Еще как вариант: на девелоперских машинах стоит что-то из опенсорса, а на боевой, например Оракл.

                                                      Кроме того, если говорить об абстракции DQL, то она не только абстрагирует нас от СУБД, но и от таблиц вообще.
                                                        +3
                                                        В том-то и дело что у меня был один такой переход с mysql на postgres.
                                                        В проекте использовался adodb для работы с базами, а все запросы обычным SQL.
                                                        И никаких проблем с переходом не было. Просто переписал пару запросов. И все.
                                                        Может мне и повезло но запросов в том проекте было много :)

                                                        в варианте: на девелоперских машинах стоит что-то из опенсорса, а на боевой, например Оракл.
                                                        по-моему очень велика вероятность выложить в продакшен код, который под ораклом будет работать неправильно. И программист не заметит этого, потому что тестит в другой субд.
                                                        Понимаю что оракл, сука, дорогой. Но в коммерческом проекта так рисковать не стоит :)

                                                        >то она не только абстрагирует нас от СУБД, но и от таблиц вообще.
                                                        Можно пример? что это дает и где это может быть полезно?
                                                          0
                                                          Можно пример?
                                                          Например, в Doctrineвской реализации Concrete Inheritance при обращении к полю topic класса Comment, значение извлекается не из таблицы comment, а из таблицы text_item.
                                                          0
                                                          Я вот считаю что абстрагироваться от СУБД и таблиц вообще несомненно нужно, но DQL — далеко не самое красивое решение. Почему это просто не реализовать классами/методами с цепочками вызовов? Было бы намного естественней с таким работать.

                                                          В DQL был бы смысл, если бы его использовали к примеру различные библиотеки причем на различных языках программирования — вот тогда да, возможно стоило бы ввести отдельный язык… и то очень сомнительно.

                                                          То есть, речь не о том, что DQL в Doctrine не нужен вовсе, речь в том, что возможно стоило бы это реализовать так, как я писал выше. Что вы думаете по этому поводу?
                                                            0
                                                            Эм, а ткните меня плиз в то, что вы описывали, а то что-то ничего найти в комментах уже не могу =)
                                                              0
                                                              Я имел ввиду реализовать это просто классами/методами с цепочками вызовов
                                                                +1
                                                                Ну, так там же есть QueryBuilder, он правда поверх DQL, конечно, написан.
                                                                или вы что-то другое имеете в виду? Я честно не совсем понимаю, в каком виде именно хочется вам видеть это.
                                                          0
                                                          Лично я — ни разу, но собираюсь.
                                                  +3
                                                  Давно слежу за развитием Doctrine 2.0, и она все больше похожа на Hibernate, что радует =)
                                                    0
                                                    Еще хотел заметить что мне кажется немного неоправданным полный переход на php5.3, docBlock ведь можно было парсить еще с выходом пятерки. В данный момент это может немного оттолкнуть начинающих разработчиков, у которых хостеры не поддерживают php5.3
                                                    Получается что они это сделали только из-за нейм-спейсов и __callStatic (ну какие есть еще в php5.3 фишки, полезные для Doctrine и используемые там, чтобы ради них отказаться от совсестимости с 5.2 веткой?)
                                                      0
                                                      static keyword, анонимные функции\замыкания — собственно это там используется, судя по коду
                                                        0
                                                        «static keyword» ??
                                                          0
                                                          static::
                                                            0
                                                            оно не совсем «static keyword» тогда.
                                                            а как оно называется правильно по версии php-dev-team документация почему-то умалчивает (или я просто не могу найти).
                                                              0
                                                              late static binding
                                                                0
                                                                LSB это техника, а не название языковой конструкции.
                                                                как называть конструкцию parent::? self::?
                                                                  0
                                                                  ну, в документации оно keyword'ом и зовется =)
                                                        +1
                                                        когда оно релизнется, 5.3 уже будет не так страшно.
                                                          0
                                                          По-моему, getDocComment доступен был ещё и до php 5.3
                                                          В любом случае, разработчики Doctrine — молодцы. Двигаются в правильном направлении.
                                                          Recess хорош, очень напоминает web2py.
                                                          Спасибо интересно посмотреть :)
                                                            +1
                                                            Да, я тоже писал что имхо — можно было и не переходить на php5.3.
                                                            Ну в принципе, да. Будем надеяться, что когда это будет стабильной версией, большинство хостеров перейдет на php5.3

                                                            По поводу web2py — действительно интересно, думал раньше что для питона джанга — вне конкуренции. Web based admin interface с генеративными возможностями это круто я считаю )
                                                              0
                                                              Для питона ещё и pylons есть :)
                                                              Дружит с SQLAlchemy, значит можно прикрутить Elixir.
                                                              И ребята из pocoo тоже крутые штуки делают!
                                                              Но вообще для топика в блоге ПХП это уже много ссылок :)
                                                            0
                                                            В Yii очень даже ничего.
                                                              0
                                                              Спасибо!!!

                                                              Only users with full accounts can post comments. Log in, please.