May 15, 2008

Zend Framework – An Example Model

Kevin Hallmark @ 3:48 pm —

Here is a little advice for people who want some guidance on creating their a model layer:

NOTE: This is merely a simple example, for guidance only. YMMV. There are a million different ways to do this kind of thing, this is merely one I have found effective.

In my apps, I generally create a BaseModel class, from which all others inherit. In this class, I’ll define a basic API that I want all models to subscribe to. This is usually something like __get, __set, setDataFromArray, validate (verify data is correct), filter (filter input data), save and other common methods.

This setup lets you change the backend storage mechanism easily. If all your model objects use the same API, you can change the underlying storage code of all your models simultaneously and your app is none-the-wiser.

An example:

Say I begin by using an array to store my data. Suddenly, I realize I want to store my data inside a database. I can change all the methods in my model to set data to a database object. Later in the project, I decide that XML would be a better choice. I can change my methods to write to an XML data file, and once again I don’t have to change my application code.

You can implement custom behavior by overriding methods and using the ‘parent’ keyword to call the BaseModel method implementation.

In most apps these days, my BaseModel class directly extends Zend_Db_Table_Row. Extending Zend_Db_Table_Row allows my model objects, with all their custom functionality, to be returned directly by Zend_Db_Table function calls. Creating lists is much faster when you don’t have to iterate the result set a second time to create model objects from them.

I usually won’t override the methods I want to use from Zend_Db_Table_Row (__get, __set, setDataFromArray). If I needed to change my storage engine I would implement these methods in my BaseModel to access the new data storage mechanism.

In each of my BaseModel subclasses, I’ll usually add some static getter methods.

For example:

Class User extends BaseModel {
Public static function getUser($user_id = null) {
//return a setup model object
$table = new users();//where users is your table class
If($user_id === null) {
$return = $table->createRow();
} else {
//get row from db

Return $return;

This function would return the model object for ‘$user_id’, or an empty object if null. You can call this method with

Each model then has a single point of origin. If I decide to change my implementation, I can be assured that “User::getUser” always will give me a fully qualified User object.

You can also create similar functions the will return a list of rows.

Hope this small bit of advice helps get your started.