views:

772

answers:

8

My question is how does one abstract a database connection from the model layer of an application? The primary concern is to be able to easily change from different types of databases. Maybe you start with a flat file, comma-delimited database. Then you want to move to a SQL database. Then later you decide an LDAP implementation would be better. How can a person easily plan for something like this?

For a simple example, let's say you have a user with a first name, last name, and email. A very simple PHP class representing it might look like this (please ignore the problems with public instance variables):

<?php

class User {
  public $first;
  public $last;
  public $email;
}

?>

I have frequently seen where people have a DAO class which has the SQL embedded in it as such:

<?php

class UserDAO {
  public $id;
  public $fist;
  public $last;
  public $email;

  public function create( &$db ) {
    $sql = "INSERT INTO user VALUES( '$first', '$last', '$email' )";
    $db->query( $sql );
  }
}

?>

My problem with strategies like this is when you want to change your database, you have to change every DAO class' create, update, load, delete functions to deal with your new type of database. Even if you have a program to auto-generate them for you (which I am not particularly a fan of), you would have to edit this program to make it work now.

What are your suggestions for how to handle this?

My current idea is to create a super class for DAO objects with its own create, delete, update, load functions. However, these functions would take arrays of the attributes of the DAO and generate the query itself. In this manner, the only SQL is in the SuperDAO class rather than being scattered about several classes. Then if you wanted to change your database layer, you would only have to change how the SuperDAO class generates the queries. Advantages? Disadvantages? Foreseeable problems? The good, the bad, and the ugly?

+1  A: 

You should look into the PDO library.

PDO provides a data-access abstraction layer, which means that, regardless of which database you're using, you use the same functions to issue queries and fetch data.

PDO does not provide a database abstraction; it doesn't rewrite SQL or emulate missing features. You should use a full-blown abstraction layer if you need that facility.

Ólafur Waage
That doesn't abstract the DB away, that just accesses it. One could _use_ PDO to create an abstraction.
Ben S
He isn't abstracting the DB away in his example. Just accessing it through precreated functions.
Ólafur Waage
I use the PDO. Unfortunately, it only handles the SQL databases which I can already handle.
Marshmellow1328
+1  A: 

It sounds good in theory but in all likelyhood YAGNI.

You would be better off using an SQL library such as PDO and not worrying about LDAP until you get there.

Greg
This is a common maintenance problem and will most likely be needed eventually. Database schemas are rarely set in stone.
Ben S
He's not talking about the schema, he's talking about seamlessly switching between CSV and relational databases. How often do you do that?
Greg
Or LDAP or any new type of database that gets invented. I wouldn't be asking the question if I didn't have a need.
Marshmellow1328
Even changing database engine is rare (say, from MySQL to Oracle) but that could be taken care of with a database abstraction layer such as PEAR::MDB2 (though maybe there is a CSV driver for that, or one could be written...)
Greg
+4  A: 

Using an ORM is usually the preferred way of abstracting the database. An incomplete list of PHP implementations is available on Wikipedia.

Ben S
+5  A: 

You can use various frameworks such as PDO, PEAR::MDB2 or Zend_Db, but to be honest in 12 years of PHP development, I've never had to transition from one type of data storage infrastructure to another.

Its exceedingly rare to even go from something quite similar like Sqlite, to MySQL. If you did do more than that, you'd have far larger problems anyway.

Alister Bulman
I use SQLite for development and MySQL for production (using Propel ORM), but my personal projects are tiny at the moment; I agree with what you said.
analytik
A: 

Generally speaking, if you're going to the trouble of using a database then your application will benefit by using features specific to a "brand" of database, and will be a more solid app for it.

It is very rare to move from one database system to another. The only time you might realistically consider that aa feature worth implementing is if you're writing some kind of loosely coupled system or framework intended for mass consumption (like Zend Framework, or Django).

EvanK
+2  A: 

Checkout this thread about ORMs for PHP: http://stackoverflow.com/questions/108699/good-php-orm-library

fredrik
A: 

I always liked using ADOdb. From what I've seen, it looks like it's capable of switching between vastly different platforms.

http://adodb.sf.net

Collin Klopfenstein
A: 

Axon ORM automatically detects changes in your schema without requiring you to rebuild your code.

stillstanding