PHP - a DB abstraction layer use static class vs singleton object?

In my most recent project, I actually went against the "good" design principles by making the database class entirely static. The reason behind this is that I used a lot of caching on PHP objects. Originally I had the database passed in through the constructor of each object as a dependency injection, however I wanted to make sure that the database didn't have to connect unless absolutely necessary.

Thus, using a database as a member variable of that object would not have been practical because if you unserialized an object from the cache, you wouldn't want to connect to the database unless you actually performed an operation on it So in the end I had only two (public) static functions, Database::fetch() and Database::execute() which would check whether or not it had already connected, and if not, it would connect and perform the query. This way I wouldn't have to worry about deserialization and would connect as seldom as possible. It technically makes unit testing impossible though You don't always have to follow every single good practice.

But I would still recommend against doing what I did since some would consider it premature optimization.

In my most recent project, I actually went against the "good" design principles by making the database class entirely static. The reason behind this is that I used a lot of caching on PHP objects. Originally I had the database passed in through the constructor of each object as a dependency injection, however I wanted to make sure that the database didn't have to connect unless absolutely necessary.

Thus, using a database as a member variable of that object would not have been practical because if you unserialized an object from the cache, you wouldn't want to connect to the database unless you actually performed an operation on it. So in the end I had only two (public) static functions, Database::fetch() and Database::execute() which would check whether or not it had already connected, and if not, it would connect and perform the query. This way I wouldn't have to worry about deserialization and would connect as seldom as possible.It technically makes unit testing impossible though.

You don't always have to follow every single good practice. But I would still recommend against doing what I did since some would consider it premature optimization.

I would say creating a SINGLETON is premature optimization, since cerating a static class is very simple. – Marco Demaio Nov 18 '10 at 17:09.

Benefits of singletons over static classes Lazy creation, which would ensure that you don't allocate memory for that object until you need it. If you include db. Inc it won't mean you allocate memory for the DB object if you don't use it.

Usage information via getInstance(); I.e. Find out who's using the singleton. You can create multiple instances of the singleton for load balancing purposes.

Construct a singleton with (constructor) parameters if necessary. Cleaner than passing parameters to an arbitrary method. You can pass the singleton class reference dynamically.

A static must always be used in a static fashion. You can extend/interface singletons, unlike static classes. I.e.

If you're building a framework. There's few reasons to use static methods since they are wonky and cumbersome and don't provide many benefits over their singleton counterparts.

1 1. A static class I don't think is so memeory greedy. - 2.

What do you mean? - 3. I need only one instance, that's why I would use either a singleton, what do you mean by creating multiple instances?

- 5. Pls show me a coded example, just few lines to show - 6. By extending you mean creating a new class that inherts the DBSingleton class?

Could you give me an idea, I know how to do inheritnace in PHP, I mean give me an example like saying: "you might need to inherit the DBSingleton because for example you want to do..." Plz reply in your answer, not as comment. Thanks! – Marco Demaio May 19 '10 at 8:32.

What is wrong with the following (simplified) example: class Database { protected $_connection; protected $_config; public function __construct( array $config ) // or other means of passing config vars { $this->_config = $config; } public function query( $query ) { // use lazy loading getter return $this->_getConnection()->query( $query ); } protected function _getConnection() { // lazy load connection if( $this->_connection === null ) { $dsn = /* create valid dsn string from $this->_config */; try { $this->_connection = new PDO( $dsn, $this->_config 'username' , $this->_config 'password' ); } catch( PDOException $e ) { /* handle failed connecting */ } } return $this->_connection; } } $db1 = new Database( array( 'driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'username' => 'test_root', 'password' => '**********' ) ); $db2 = new Database( array( 'driver' => 'pgsql', 'host' => '213.222.1.43', 'dbname' => 'otherdb', 'username' => 'otherdb_root', 'password' => '**********' ) ); $someModel = new SomeModel( $db1 ); $someOtherModel = new SomeOtherModel( $db2 ); $yetAnotherModel = new YetAnotherModel( $db2 ); This demonstrates how you can make use of lazy loading connections, and still have flexibility to use different database connections. The database instances will only connect to their individual connection when an object that consumes one of the instances (in this case one of the models) decides to call a method of the instance.

Sorry, but I don't undertsand your example. 1) it's not a Singleton, but a genric class, so it's obvious that you can create multiple istances to differnet DBs that's what a generic class is meant to be, on contrary a SIngleon is meant to return you always the same object with the same connection. 2) when you say " this example", even the static class and the Singleton only connetcs when needed, the init fucntion simply strores the DB connection parameters, the connection is performed only if needed duirng the call to the query function (read comments in my question code).

– Marco Demaio Aug 13 at 10:25 Marco, the reason I advise against using a singleton is because, when your application (or a future application) needs two different database connections at the same time, you can't use that class anymore, because it can only accommodate for one connection. Furthermore I presume you use this singleton to easily get the instance from anywhere you like, right? But that creates strong coupling.

However, when you pass the database connection to the constructor of the consuming object, as in my example, you create loose coupling, so you can easily swap it for another class with the same interface. – fireeyedboy Aug 13 at 16:33 oh I didn't understand you were actually suggesting not to use a Singleton or static class at all, but to use a normal class. Now I understood your point.

– Marco Demaio Aug 16 at 17:09 @Marco: no problem. Hope it's useful information, as well as a useful example for you. I'd strongly advice you to this route anyway.

– fireeyedboy Aug 16 at 17:37.

My advice: STOP using Singleton and static all together. Why? Because you will insert dependencies that will render your code unusable in other projects, and will not allow to unit test it.

Also forget about loose coupling if using singleton. The alternatives? Dependency Injection.

potstuck.com/2009/01/08/php-dependency-i....

In my most recent project, I actually went against the "good" design principles by making the database class entirely static. The reason behind this is that I used a lot of caching on PHP objects. Originally I had the database passed in through the constructor of each object as a dependency injection, however I wanted to make sure that the database didn't have to connect unless absolutely necessary.

Thus, using a database as a member variable of that object would not have been practical because if you unserialized an object from the cache, you wouldn't want to connect to the database unless you actually performed an operation on it. So in the end I had only two (public) static functions, Database::fetch() and Database::execute() which would check whether or not it had already connected, and if not, it would connect and perform the query. This way I wouldn't have to worry about deserialization and would connect as seldom as possible.

It technically makes unit testing impossible though.

What is wrong with the following (simplified) example.

In my most recent project, I actually went against the "good" design principles by making the database class entirely static. The reason behind this is that I used a lot of caching on PHP objects. Originally I had the database passed in through the constructor of each object as a dependency injection, however I wanted to make sure that the database didn't have to connect unless absolutely necessary.

Thus, using a database as a member variable of that object would not have been practical because if you unserialized an object from the cache, you wouldn't want to connect to the database unless you actually performed an operation on it.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions