views:

731

answers:

4

I am looking into using Doctrine2 with my Zend Framework setup. I really like the datamapper pattern, mainly because it seperates my domain models with my database.

My question is what is the best practice for using Doctrine and DQL with my controllers?

  1. controllers uses Doctrine DQL/EntityManager directly for saving/loading my domain models?

  2. create my own classes in the datamapper pattern for saving/loading my domain models, and then use Doctrine internally in my own classes?

The pros. for #1 is of course that I don't need to create my own datamapper models, but again, with #2 I can later replace Doctrine (in theory)

What would you do?

+1  A: 

Also consider Symfony in your research. It will let you use ORM(propel/doctrine) or you may write your own data model. You can also bypass the data relationship and use direct SQL if needed.

To address your concern on 1 or 2, I personally go with ORM in my projects and bypass it if need arises. And better yet with symfony, you may switch between doctrine and propel or your own classes if you ever need to.

Pros:
1) faster development. easier to maintain. generally more secure and consistent. easy to switch databases should you ever need to.(from MySQL to Oracle, etc). 

2) Faster runtime. Less dependency.

Cons:
1) Slower runtime and larger memory footprint. Dependency on other projects.
2) (reverse the pros for #1)
Mohammad
Thanks for your input, but i wan't to use Doctrine2 in both #1 and #2 it is just a question if I wan't abstract Doctrine away or i should use it directly.
SuneKibs
+1 for symfony, it rocks.
Peter D
+1  A: 

Regarding your abstraction question, I'd say it really depends on the lifetime of this project and how portable your code needs to be. If it's a one-off website that will need minimal maintenance, it would probably save you some time to forego the additional abstraction layer and just write Doctrine code in your controllers. However, if you're planning to reuse this code, move it to different platforms, or maintain it for a long period of time, I'd take the time to add that abstraction because it will give you a lot more flexibility.

If you're still researching frameworks, take a look at Kohana. It's basically a lightweight rewrite of CodeIgniter written for PHP5.

pix0r
Thats for the very good input regarding the abstraction.About frameworks, I have used ZF since v. 0.2 and really like this Framework, used it for at lot of projects. Never heard of Kohana, but will look into it.
SuneKibs
@pix0r, Kohana is a rewrite of CodeIgniter, not Symfony
Arms
Haha, you're right. Thanks. (edited)
pix0r
+1  A: 

I second the advice from pix0r. The additional abstraction is only worth it if it is a larger project with a potentially long lifetime and maybe with many developers on it. This is pretty much the guideline I follow, too, be it in php with doctrine2 or in java with jpa (since doctrine2 heavily resembles jpa).

If you want the additional abstraction, doctrine2 already ships with the possibility to use repositories (repositories are very similar or even equal to DAOs, maybe with a stronger focus on the business terms and logic). There is a base class Doctrine\ORM\EntityRepository. Whenever you call EntityManager#getRepository($entityName) Doctrine will look whether you configured a custom repository class for that entity. If not, it instantiates a Doctrine\ORM\EntityRepository. You can configure a custom repository class for an entity in the metadata, for example in docblock annotations: @Entity(..., repositoryClass="My\Project\Domain\UserRepository"). Such a custom class should inherit from EntityRepository and call the parent constructor appropriately. The base class already contains some basic find* functionality.

Roman