PDO или ORM в PHP?
====================

 Раньше я разрабатывал все проекты на основе PDO DB. Сейчас прочитав много книг и статей, начал задумываться а правильный ли я подход использую? Везде идут советы по использованию Doctrine или Propel, как более удобное средство. Да, формат работы по приведённым примерам мне понравился. Но вот смогут ли эти библиотеки создавать сложные запросы с несколькими например JOIN'ами, и вообще как скажется использование этих библиотек на производительности?  
  
  
  

Поэтому вопрос к общественности: «Чем Вы пользуетесь для доступа к БД, и почему Вы выбрали именно данный способ?». 

 Простые запросы (их процентов 80) орм упрощают конечно, а вот если надо нестандарт, то проще нативным sql сделать. Имхо конечно. 

 Тоже задавался подобным вопросом. Пробовал доктрину и пропел, но откинул их ввиду большой прожорливости и костылей при сложных запросах. Также раздражало огромное количество вспомогательных файлов (базовые классы, мапперы и т.п.) на каждую модель, сгенерированные этими библиотеками. В итоге сделал свою ORM на базе Zend\_Db\_Table, Zend\_Select (это особенно выгодно, когда сам проект построен на ZF).  

Для простых случаев удобно использовать Active Record. Самым удачным примером реализации считаю AR в фреймворке Yii. 

 Мне нравится подход, используемый в Yii framework — простые запросы можно реализовать с помощью ORM, а для сложных есть более низкий уровень абстракции, основанный на PDO. Таким образом можно сочетать оба подхода в зависимости от сложности того или иного элемента проекта. 

 Есть такая вещь как форум по php: [www.phpclub.ru/](http://www.phpclub.ru/)  

Где есть поиск, и гораздо больше опытных людей (а не (больше) новичков как на хабре).  

Хотя искренне надеюсь, что и здесь смогут подсказать… 

 Использовал доктрину (в симфони) — удобно, джоины делать можно. Все наглядно и красиво, есть документация.  

Из минусов — потребляет много памяти. 

 Doctrine (для рутины) + PDO (для клинических случаев) FTW 

 Ошибка в понимании разницы между PDO и ORM, вопрос звучит как «ложка или тарелка за ужином»  

  

PDO это DBAL — простой интерфейс для работы с базой данных, который предоставляет одинаковые методы для работы с различными базами данными, поэтому вам не надо задумываться с какой именно БД мы работаем в текущий момент.  

  

ORM — из википедии — is a programming technique for converting data between incompatible type systems in object-oriented programming languages. Т.е. техника конвертации обычных таблиц, как в реляционных бд, в объекты. Это и очевидно, с обычными массивами работать трудно, а FETCH\_OBJECT это всеравно не ОО-подоход.  

  

Одна технология дополняет другую.  

  

Теперь про propel и doctrine.  

  

Doctrine 1 мне не понравился потому, что в него добавили кучу непонятных фич и в конечном результате вышла каша, трудная для изучения (для примера, три способа извлечения данных из сущности, непонятная абстракция 'Table').  

  

Propel. скорее мертв, чем жив. Его поднял и поддерживает сейчас только один человек. Не понравился тем, что на одну сущность генерируется 6 непонятных классов, да и сам процесс генерации надоедает  

  

Doctrine 2 это практически hibernate для php %) по сравнению с первой версии его очистили от мусора, сделали его data mapper-ом. Что нравится — это понятный интерфейс, чистые доменные объекты (сущности) — весь конфиг можно вынести в аннотации/xml/yaml. В результате все модели выглядят так же просто, как и class news {private $title; private $text; }. Остановился на нем. 

 Мы одно время думали, как перейти на ORM, рассматривали Propel, но потом внедрили Yii и стали использовать его встроенный ActiveRecord. Для большинства задач — вполне себе превосходно справляется.  

Ну а для сложных, а особенно больших выборок (более тысячи записей) использование ORM крайне не рекомендуется. 

 ОРМ хорош когда много простых запросов и сущности предметной области хорошо ложатся на структуру бд — ускоряет создание классов-моделей. Сложные запросы с помощью методов, которые предоставляет ОРМ, писать обычно долго и скорее всего выйдет не очень понятный и красивый код. Тут уж имхо лучше нативный SQL. 

 Бывают случае когда ORM не справиться с запросом. Просто никак.  

И бывают запросы когда и нативный ввод SQL тоже не справиться с запросом.  

Проблемы бывают как технические, так и архитектурные или скоростные.  

  

Но в любом случае — чем хитрее и оригинальнее обвязка над конечной БД — тем лучше.  

Начиная от работы с базой в несколько конектов, заканчивая работой с несколькими базами, или таблицами партироваными на несколько серверов. Или даже прямым отображением на сфинкс.  

  

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

Соберите в единую систему.  

И под эту систему ищите инструмент.  

Но совсем чистый SQL не используйте никогда — как минимум запросы через свою обертку. Как минимум возмонжость как либо легко менять(или находить в запросе) имена таблиц. 

 По моему опыту, при тонкой настройке библиотек, реализующих ORM (прежде всего настройка lazy load чуть ли не для кждого запроса) оверхид при выполнении от них небольшой (по сравнению с собственно выполнением запроса) и полностью компенсируется упрощением разработки и поддержки, если не требуется использовать «экзотику» типа хранимых процедур или триггеров. 

 Скажу где не надо использовать Doctrine 1.2 или Propel — в long-running scripts.   

Доктрина жрет память на ровном месте и с этми никак не справитесь, рано или поздно достигните лимита по памяти.   

В остальных случаях выбор ОРМ оправдан. 

 Когда-то я вообще не понимал, зачем эти ORM нужны - ведь можно написать миниатюрную оболочку над mysqli/PDO и пользоваться ей (что и делал в домашних проектах, а на работе в то время работал с Yii2 и Active Record соответственно, который совершенно не нравился), до тех пор, пока... на своем самописном велосипеде не столкнулся с задачей:  

1. Взять все поля из таблицы с 70+ колонок  

2. Сделать форму, с редактированием каждого поля  

3. Сохранение обновленных данных  
  

То, что на ORM делается несколькими строчками - мне, в моей небольшой обертке, пришлось делать весь вечер - прописывать все поля, прописывать каждый input и т.д. В общем в тот вечер я понял, зачем нужны ORM :)  
  

Хотя, с точки зрения производительности - чем тоньше прослойка между проектом и базой - тем лучше. 

 ORM и нативный SQL это совершенно разные подходы и каждый решает для себя и для каждого конкретного проекта, что использовать.  

Если вы вдабавок к SQL разберётесь с ORM, вам будет только плюс к опыту. Вот только советы использовать доктрину идут далеко не везде. 

 Помимо самого ОРМ (т.е. возможности работать с записями из таблицы как с экземплярами класса) очень полезен и конструктор запросов, хоть он и кажется инородным и неудобным на первый взгляд.   

  

Например использование пропелевского Criteria значительно упрощает процесс сборки сложных запросов и улучшает читаемость кода (прощайте бесконечные спринтф и другие операции со строками), возможностей хватает в 99% процентов случаев.   

Если гидрация (процесс формирования объектов из результата запроса) окажется ботелнеком, например при выводе большего списка с джоинами в кучу таблиц — в пропеле можно от нее отказатся и использовать pdo::fetch, при этом используя критерий.  

  

Полагаю что доктрин обладает аналогичным функционалом. 

 ORM очень удобная штука. Многие реализации позволяют выполнять не только простые запросы но и всякие джойны, юнионы, подзапросы и т.п. Я в cakephp в рамках проекта несколько раз пользовался «сырыми» запросами для реализации более изощренной логики. Однако после более внимательного прочтения документации оказывалось, что все это было сделать проще в рамках функционала ORM.  

В любом случае любой ORM позволяет выполнять «сырые» запросы, так что проблем возникнуть не должно. 

 Зависит от задачи, если это простой сайт с админкой на принципе CRUD, то ORM значительно упрощает и ускоряет разработку.  

Если же это высоконагруженный проект, то ORM может дать излишний оверхэд и подводить на сложных запросах.  

  

Но, ничего не мешает совмещать оба подхода, например ORM для админки и DAO для фронтенда.  

  

Советую посмотреть на реализацию ORM и DAO в Yii. Прочитайте [раздел про БД в гайде](http://www.yiiframework.com/doc/guide/1.1/ru/database.overview), оцените возможности обоих подходов. 

 Использую Doctrine + собственные расширения этой замечательной ORM. По поводу прожорливости по памяти, там есть прекрасный кэшер запросов, который кэширует операцию парсинга DQL запроса в SQL. Другие тормоза могут быть из-за:  

1. Здорового запроса с кучей JOIN'ов. Но тут как-бы не к Doctrine вопросы.  

2. Большой объем выборки. Собственно надо лимитировать и будет всё ок. Или опять же кэшировать.  

  

Самый большой плюс Doctrine, как мне кажется — это возможность подкрутить, то что тебе надо, и где тебе надо, чем я регулярно и пользуюсь, поддерживая свою библиотеку расширений (не трогая сам дистрибьютив). Т.е. можно довольно спокойно писать как высокоуровневые запросы а ля DSL, так и низкоуровневые запросы с помощью NativeSQL.  

Насчет кучи файлов уже есть решение, php5-fpm + apc cacher. Грузится один раз и остается висеть в памяти.  

Да, вторая будет ещё лучше. Планирую перейти на неё, как выпустят :-)