Simplify Business Logic with PHP DataObjects
by Darryl Patterson08/05/2004
Simple Data Objects with PHP 5
Working with a database is an everyday exercise for web developers these days. From simple form processing to large-scale web applications, we almost always need a database. After working on a few projects, it doesn't take very long to realize that the same four simple database tasks repeat many times in virtually all projects. These four tasks are:
- Finding records (
SELECT). - Updating existing records (
UPDATE). - Adding new records (
INSERT). - Removing records (
DELETE).
You find yourself re-typing or copying and pasting your queries throughout your code, slightly modifying them as necessary in various places. Many folks resort to a data abstraction layer, such as Pear::DB or DBX. Using a data abstraction layer is a good thing, but its main goal is to make the RDBMS transparent, allowing you to change database vendors fairly easily. A database abstraction layer doesn't offer a way to abstract the table structure of your database, since it can't standardize the way your functional code accesses data in your database. This is where having a separate data access layer can help out. You can implement data access layers in more than one way, but here, we're interested in DataObjects.
The concept of DataObjects comes from some very well-documented design patterns, namely the Data Access Object and Transfer Object patterns. These patterns can be quite complex, but with a little imagination, we can use their fundamental ideas and purpose to make our own data layer in PHP 5 much easier to work with. Let's dig in.
What is a DataObject?
As just mentioned, the idea of a DataObject comes from a design pattern. If you've ever looked into design patterns at all, you'll know that they often depend on object orientation. That said, we will make extensive use of PHP 5's new object model. We'll also use MySQL for the examples (although it's also easy to use something like Pear::DB).
Essentially, a DataObject is a coded class that directly represents a table in your database -- you will code a class for every table. The class will have member variables that exactly match the fields in your table, as well as a set of methods or functions that perform at least the four basic tasks mentioned above. Suppose we have a simple table for holding user info:
TABLE: User
userId INT
firstName VARCHAR(30)
lastName VARCHAR(40)
email VARCHAR(100)
Now that we have a table, we'll code a corresponding class whose member
variables have the same field names found in the table. I tend to prepend my
DataObject class names with DO_ to avoid confusing them with other
classes of similar names; this is a common pattern in PHP to simulate
namespaces. Here's the code:
class DO_User {
public $userId;
public $firstName;
public $lastName;
public $email;
}
This simple little wrapper represents a single row from our table. An
instance of DO_User can hold only one row of data at a time. How
do we fetch data from the database into this object? Let's add a new method called get() to
our class to query the database for one specific
user. We'll provide the userId (the primary key) of the user we
want to fetch as a parameter.
File contents of: class-DO_User.php
<?php
class DO_User {
public $userId;
public $firstName;
public $lastName;
public $email;
// This function will perform a select on the table looking for
// a specific userId.
public function get($userId)
{
$sql = 'SELECT * FROM User WHERE userId='
. mysql_escape_string($userId);
$rs = mysql_query($sql);
$row = mysql_fetch_array($rs);
$this->userId = $row['userId'];
$this->firstName = $row['firstName'];
$this->lastName = $row['lastName'];
$this->email = $row['email']
}
}
?>
With this very simple data object, we can now interact with our database using only PHP code. We need no SQL to use our database. Here is a script that uses this DataObject to fetch and display the user's data to a web browser:
<?php
include_once('class-DO_User.php');
$user = new DO_User();
// We'll use a literal integer here,
// but this could come from anywhere,
// such as $_POST or $_GET
$user->get(5);
?>
<html>
<head>
<title>User Info</title>
</head>
<body>
<p>Here is the user info:</p>
<table border="1">
<tr>
<td>User ID</td>
<td><?=$user->userId?></td>
</tr>
<tr>
<td>First Name</td>
<td><?=$user->firstName?></td>
</tr>
<tr>
<td>Last Name</td>
<td><?=$user->lastName?></td>
</tr>
<tr>
<td>Email</td>
<td><?=$user->email?></td>
</tr>
</table>
</body>
</html>
As you can see, using the DataObject is quite simple and very clean. The
get() method we added performs a simple query on the user table,
searching for the specific primary key (userId) for which we're looking.
Remember, whenever you query a table looking for equality on a primary key,
you'll only receive one record back. This works well for our simple DataObject,
but we'll discuss retrieving multiple rows a little later.
Notice that when the DataObject has found the record, it copies the record data into the DataObject's member variables. This is why the names of the member variables in the DataObject must match the column names in the table exactly.




