Decoupling models from the database: Data Access Object pattern in PHP
January 5, 2009 – 1:07 pm Tags: , Doctrine, PHP, Programming, source codeNowadays it’s a quite common approach to have models that essentially just represent database tables, and may support saving the model instance right to the database. While the ActiveRecord pattern and things like Doctrine are useful, you may sometimes want to decouple the actual storage mechanism from the rest of the code.
This is where the Data Access Object pattern comes in. It’s a pattern which abstracts the details of the storage mechanism – be it a relational database, OO database, an XML file or whatever. The advantage of this is that you can easily implement different methods to persist objects without having to rewrite parts of your code.
I’m again going to use the programming language quiz game I wrote as an example. Since I initially wrote it to use Doctrine ORM directly, and both the old and new code are available, you can easily see how the code was improved.
A look at the pattern

The basic idea is that you have a Data Access Object (DAO), which abstracts the storage mechanism. It should implement an interface, so if you want to add another way of accessing data, you simply write a new set of DAO’s that implement the interface.
While you could use the pattern alone, it’s probably best to use it together with the factory pattern. That way, we have a single class which handles the creation of the DAO’s – the DAO factory. We could even have multiple factories to handle creation of different kinds of DAO’s, and use the abstract factory pattern to hide the implementation details.
The image on the right displays how the abstract factory version of this could work. Basically, you have an interface HelloDao, which is then implemented by your concrete DAO objects. You also have an interface for the factory, and the concrete factory/factories implement it.
The example later in this post, however, uses just a single factory, as we only implement a single set of DAO’s.
The models
The models in the quiz are relatively simple. We have Question, Answer and QuestionAnswer. At first, these were just Doctrine’s models. However, for implementing the DAO stuff, we’ll create some new model classes of our own.
Here’s the Quiz_Question model class:
<?php class Quiz_Question { private $_id; private $_question; public function getId() { return $this->_id; } public function setId($id) { if(!is_numeric($id)) throw new InvalidArgumentException('ID can not be non-numeric'); $this->_id = $id; } public function getQuestion() { return $this->_question; } public function setQuestion($question) { if(empty($question)) throw new InvalidArgumentException('Question can not be empty'); $this->_question = $question; } }
Quite simple. It just stores an ID and the question’s text, and provides getters and setters. The setters contain a bit of validation logic that throws an exception if the data is bad. There is absolutely no persistence-related logic here.
The other model classes follow this same approach.
Creating a DAO for the question model
Here’s an interface for the DAO that will be used to deal with Questions:
<?php interface App_Dao_Question_Interface { public function insertQuestion(Quiz_Question $question); public function findQuestion($id); public function fetchRandomQuestionNotIn($questionIdList); public function findQuestionByQuestion($question); }
You can probably see the basic idea there: The interface provides methods for accessing the data, as the name Data Access Object says.
Since I still want to use Doctrine, I’m going to create a DAO which uses Doctrine’s methods to implement the above interface:
<?php class App_Dao_Doctrine_Question implements App_Dao_Question_Interface { /** * Insert a question into the database * @param Quiz_Question $question */ public function insertQuestion(Quiz_Question $question) { //Create a Doctrine model for storing the Quiz_Question model $q = new Question(); $q->question = $question->getQuestion(); try { $q->save(); $question->setId($q->id); } catch(Doctrine_Exception $e) { throw new App_Dao_Exception('Error inserting question', $e); } } /** * Find a question by ID * @param int $id * @return Quiz_Question */ public function findQuestion($id) { try { $data = Doctrine::getTable('Question')->find($id); } catch(Doctrine_Exception $e) { throw new App_Dao_Exception('Error querying the database', $e); } if(!$data) return null; $question = new Quiz_Question(); $question->setId($data->id); $question->setQuestion($data->question); return $question; } /* Rest omitted to save space */ }
Here are two methods from the interface implemented in the DAO. You can see how the methods basically hide away the fact that it’s Doctrine behind the scenes. Particularily, note the try-catch blocks – they are used to catch any implementation-specific exceptions from Doctrine, which get wrapped into App_Dao_Exceptions. This way you can easily catch exceptions from the DAO’s, without knowing what it’s doing behind the scenes.
Creating the factory
Now we have some models, and DAOs that interact with the storage (the database in this case). Next, we need the DaoFactory.
Strictly speaking, this class isn’t absolutely necessary. We could create new DAO’s in our code without the factory, but it might not be a very good idea. If some DAO’s need more initialization, for example passing in a database connection or something, it would be problematic.
Also, if we wanted to change the DAOs, we would need to go around our code and modify it to create other kinds of instances. With the factory, we could simply modify (or even replace) the factory and all code will follow.
class App_DaoFactory { private static $_instance; public function __construct() { } /** * Set the factory instance * @param App_DaoFactory $f */ public static function setFactory(App_DaoFactory $f) { self::$_instance = $f; } /** * Get a factory instance. * @return App_DaoFactory */ public static function getFactory() { if(!self::$_instance) self::$_instance = new self; return self::$_instance; } /** * Get a Question DAO * @return App_Dao_Question_Interface */ public function getQuestionDao() { return new App_Dao_Doctrine_Question(); } }
The factory is set up a bit similar to the singleton: it has a static method for getting an instance of the factory. This is so we can easily obtain a factory instance in our code, but we also provide a setter method, so if needed, we can replace the factory with something else – for example a mock factory for testing code, as can be seen in the new unit tests for App_QuizHandler (scroll down in the code).
This could be easily changed into an abstract factory too. The getFactory method could return PdoDaoFactories, DoctrineDaoFactories or something else – perhaps based on a parameter that’s passed in, or a configuration value or something. But since the abstract factory isn’t necessary (we could just change the get*Dao methods), I have left it out.
DAO in action
With all the classes done, we can now move to actually using them in code. Here’s a very simple example:
$questionDao = App_DaoFactory::getFactory()->getQuestionDao(); $question = $questionDao->findQuestion(10);
Relatively simple, no?
Let’s check out a few examples from the quiz on how the code was changed. For example, if we look at the App_Questioner class, methods getRandomQuestion or getBestAnswer, we can see that there’s a bunch of Doctrine-related code there. Looking at the refactored App_Questioner, we see it’s mostly replaced by calls to the DAO’s. Also, if you check out the DAO’s code, you can see the code was basically just moved to the DAO method with minor changes.
Summing it up
While going straight Doctrine models may be quick, DAO’s provide flexibility where it’s needed, and you could easily write some tools to generate the DAO classes for you. Of course, it’s a layer of complexity, but it’s good to know different ways of solving problems.
What comes to the model class shown, and the fact that there is no database related logic… It could contain some additional methods, for example getAnswers, which could return relevant answers. If we provided a such method, it should use the DAO for the answers to fetch them.
The approach with DAO’s is a bit similar to what Matthew Weier O’Phinney shows in his model infrastructure blogpost. I recommend checking it out, as it also contains some more in-depth things about models themselves.
The Core J2EE patterns: Data Access Object is also a good read on the topic.
The source code for the quiz can be found in SVN, as follows:
Version 1.0 of the quiz
Version 1.1 of the quiz (with DAO’s and some other refactoring)
Further reading:
Another idea for using models with forms
The problems faced by a common model interface in frameworks
Food for thought: utilizing models in MVC


22 Responses to “Decoupling models from the database: Data Access Object pattern in PHP”
Very interesting stuff. I’ve been experimenting with something similar, specifically to try and move more functionality out of the Controllers in my applications and into more of a Model.
One thing I’m quite interested in is subsequently mocking the DAOs for unit testing, i.e. where your controller may do App_DaoFactory::getFactory(), my controllers would have a factory instance injected into them.
Have you done anything like that?
By Ciaran McNulty on Jan 5, 2009
Injecting the factory is one possible future improvement in the quiz code.
For now, the unit tests just mock the factory, and use setFactory. See QuizHandlerTest.php
What comes to dependency injection, you might want to check out Sphicy by Benjamin Eberlei. It seems like a good approach to dealing with DI.
By Jani Hartikainen on Jan 5, 2009
Since I switch from php 4 to php 5, I keep wondering why one wants to push a dynamic language to behave as a static one?
Is it for performance? no, cause as more classes, interfaces, … more includes == slower.
So why?
By PHP Programmer on Jan 5, 2009
I know you’re not touching on MVC in this post, but one option I’ve played with recently in ZF is injecting the DAO factory (which I tend to call a MapperFactory) into the Controllers using a Controller Plugin.
I’ll try and solidify it into some coherent thoughts / concrete code / a blog post at some point.
By Ciaran McNulty on Jan 5, 2009
PHP Programmer,
Because it’s possible?
You could probably throw away the interfaces and just use duck typing, but when the objects need to have a certain set of methods for others to be able to use them, I think an interface is the answer.
The code is easier to write/maintain/test too.
The performance hit isn’t that high if you use opcode caches. You can also combine multiple files into one to reduce the overhead of disk IO
By Jani Hartikainen on Jan 5, 2009
Hi Jani,
nice post! I think DAO is the most natural way of using OOP.
Looking at your Quiz_Question class I noticed a lot of redundant code there. You have to implement an accessor method for every field in the class and the validation logic will be duplicated across objects either. I think it will be interesting to use some magic methods in the concrete objects or even AOP to eliminate this duplication.
Yours,
sas171
By sas171 on Jan 5, 2009
Good point. Though depending on the models, your end result in code-duplication department may vary. I think mainly the IDs are what could be validated with the same logic. More complex models might require more model-specific validation rules.
Anyways, the getters and setters were generated by NetBeans, so I didn’t really write any of it myself (except the validation)
By Jani Hartikainen on Jan 5, 2009
Hi
Can you tell me why DAO?
It boosts decoupling between models, which is terrible approach.
Look at any UML diagrams. In most cases there is no Peer or DAO – just domain objects.
So BlogModel will provide methods to retrieve (and populate if necessary) ArticleModels. ArticleModel can initialize (populate) itself or obtain CommentModels and so on.
What else? You can create sophisticated SearchModel or MenuModel which are totally decoupled from persistence mechanism and schema. Models should reflect application logic.
IMO DAO is bad idea because it violates internal flow.
Cheers, Alan
By Alan on Jan 5, 2009
It depends on the approach taken. You could create an all-powerful domain object, which hides the DAOs – If you take a look at the J2EE pattern page, the diagram there shows a business object using the DAO. In essence, the QuizHandler and Questioner classes in the Quiz are business objects, and they contain most of the DAO logic.
The only “bad” things about the DAO pattern (in my opinion) is that it adds some complexity, and requires you to write (or generate, if you have a tool) some extra code.
By Jani Hartikainen on Jan 5, 2009
You make your models anemic. Consider this as smasher
By Alan on Jan 5, 2009
@Ciaran McNulty
I worked with Alan Brown in 2005
The same year you won a book at the PHP conference.
Sorry Jani for hijacking your post.
By Federico on Jan 5, 2009
Hi, I like what you are suggesting here. But I would suggest to refactor the App_DaoFactory to several factories cause now it is coupled to all other dao implementations. This will make it more more reusable by other applications.
Instead I would create QuestionDaoFactory, MyOtherDaoFactory and so on. And simply use it like QuestionDaoFactory::getQuestionDao(). Also it would be nice to add a setter to the factory for the QuestionDao to make it easy to have it replace in unit test and so.
Thanks for a good post.
By Johan Nilsson on Jan 8, 2009
This is an old post, but I noticed that you have a couple dependencies in
class App_Dao_Doctrine_Question implements App_Dao_Question_Interface
Would you still do this the same way?
By Stephane on Jul 17, 2012
@Stephane It’s not something that’s absolutely necessary, but I think it’s helpful in that it allows you to use parameter typehints or other things like that and tells you the generic interface the class will have.
By Jani Hartikainen on Jul 18, 2012