0

I'm creating an application that I want to run on either MySQL or SQL Server (not both at the same time) I've created two PHP classes DatabaseMySQL and DatabaseSQLSVR and I'd like my application to know which database class to use based on a constant set up at install.

define(DB_TYPE, "mysql"); // or "sqlsrv"

I'm trying to think of the best way to handle this. My thought is to do an "if else" wherever I instantiate the database:

$db = (DB_TYPE == "mysql") ? new DatabaseMySQL : new DatabaseSQLSVR;

I know there has to be a better way of doing this though. Suppose I want to add a third database type later; I'll have to go and redo all my code.

2
  • 1
    The reality is that, unless extremely simple SQL, you'd have to tweak statements anyway. But it's the way to go if you want top performance. Commented Jun 13, 2010 at 18:31
  • And you can always use a switch ... case statement instead of if ... else if ... else. Of course, there are much better solutions, see answers below Commented Jun 13, 2010 at 22:20

5 Answers 5

1

In the simplest possible terms:

Use define to define 'DB_TYPE' as YourFullyQualifiedClassName, then...

define('DB_TYPE', 'DatabaseMySQL') // or DatabaseSQLSVR or ...
$myDBType = DB_TYPE;
$db = new $myDBType();
Sign up to request clarification or add additional context in comments.

3 Comments

I would recommend having some (abstract?) base class to inherit from and check if your new instance indeed inherits from that class (see php.net/instanceof)
Kris, I have made a "Database" superclass that both classes extend; It just seemed like the right thing to do. But, to be honest, I'm not sure how it will benefit me at this point?
it benefits you because everything you override in your more specific classes has to remain compatible with the shared baseclass. other code where you talk to your more specific instance can now just assume it is talking to the more generic baseclass without worrying about actual implementation.
1

You should look into to using a technology such as PEAR.

Here is a good article on PEAR. http://www.evolt.org/node/21927

3 Comments

PEAR looks interesting. Note that you still need to write version-specific SQL statements yourself though to either get maximum performance, or to accomplish things that aren't standard SQL but are supported differently on different DB's.
I agree, if your requirement is to support multiple DBMSs, then use a library.
I checked it out and it looks like PEA::DB supports multiple db connections spontaneously. I'm not sure I want that kind of memory usage. Not to mention I've already built my database classes.
0

I suggest you create two data access objects that performs the various DB actions your application requires. Use the Factory Pattern to return either the MySQL or MS SQL implementation, and do all data access in your PHP pages using that data access object.

That way, you can tune behavior (as OMG Ponies suggests) as needed for each target database. If you use a common base class, you can inherit the same implementation for both databases and only provide a specific implementation where warranted (though I have not done much OO PHP... not sure if inheritance is supported?).

1 Comment

Yes, I could have Database superclass.
0

The usual way is to have them both called the same (say, Database) and each placed in a separate file. Then you would need:

define(DB_TYPE, "mysql"); // or "sqlsrv"
require('db/' . DB_TYPE . '.php');

and you could just $db = new Database();

EDIT: Note that it is essential for your system to work properly to have an interface that both classes implement accordingly.

2 Comments

that could nicely mess up any autoloading in place and also screw you over if you're using a proper IDE (code completion will not know what class to use for "Database") i'd say bad idea.
Not if they implement the same interface. Besides, the classes must most certainly use the same exact methods for the whole thing to work properly.
0

The problem is that there's some odd bit of syntax which you never planned for which is handled in a radically different way by different drivers - e.g. explain plans, transactions...

A good starting point would be to use a common abstraction toolkit such as dbx, adodb, or PDO.

In each case, the DBMS driver can be referenced as a data item in the same way as the username or password - no conditional statements.

C.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.