Bill
Bill

Reputation: 141

Singleton PHP - database handler

I have been reading a bit lately about the singleton pattern. When readin the technical aspects of it, it appears to be ideally suited to managing a database handler or the likes. But after reading wider resources it appears that the developer community really does not favour the pattern.

I am struggling to find a better solution to such a problem - i.e. only a single handler can be initialised at a time - so why is the pattern so bad? Is it overused or is it just fundamentally flawed?

Php is the language that I am using.

Upvotes: 8

Views: 1640

Answers (5)

Manos Dilaverakis
Manos Dilaverakis

Reputation: 5869

Apart from the global variable thing the community dislikes Singletons because eventually there's a chance you'll need an extra instance of the class. For example you may use a Singleton for your database connection and it works great up until the moment when you want to connect to 2 databases as once. At that point you either refactor your entire app or you copy-paste the singleton to a new class and use that. Either way you're up a certain creek without a paddle.

However the Singleton pattern is a design pattern, not an implementation. Nobody said that the code that restricts you to one instance has to be within the class. I have found that if you instantiate the class via a factory method you can put the singleton implementation in the factory method. Then if one day you need a new instance you can add a new factory method to do just that since the class itself doesn't have any restrictions. The price for this of course is that you always instantiate your singleton via a factory and not directly.

Upvotes: 0

Mark Grey
Mark Grey

Reputation: 10257

I use a singleton database handler for most of my smaller web apps. When coupled with an external configuration file and PDO as the method of database access, it can still be very flexible moving from project to project, so long as the methods are not application model specific (ie, getRow or getAll instead of getThing or getBreakfast). I just try and make sure that all my access constants are defined separately.

A lot of the chagrin for singletons is derived mainly from languages more complex than PHP.

Upvotes: 0

quantumSoup
quantumSoup

Reputation: 28132

Some people follow this mantra that Singletons are evil because they are like global variables and make your code more hard-coupled and harder to test.

I for one don't think it's such a bad idea, and I think a Singleton works pretty well for a database handler. It's easy, intuitive, and you have more control over a Singleton instance than you would a global variable.

Upvotes: 2

Stephen Melrose
Stephen Melrose

Reputation: 4830

There's nothing wrong with the Singleton pattern, I use it all the time.

As you say, it is ideal for resources you should only have one instance of and that are global to the application.

I think some developers don't like it due to dependencies that can be created through this method. Read up on Dependency Injection as I think it covers why Singletons are bad, but I can't remember exactly.

Upvotes: 0

Charles
Charles

Reputation: 51411

Singletons are glorified global variables. The design pattern was created for languages in which global variables are difficult or impossible, or where they are considered bad practice. (In fact, most of the common design patterns are designed for restrictive languages. A great number of them are simply unnecessary in other languages.)

PHP has global variables. PHP global variables are usually a bad practice, but they do exist if you need to use them.

However, there are a few reasons you'd want a Singleton in PHP.

Singletons are useful when the call to getInstance (the canonical name for the method that returns the single instance of the Singleton) might me made at any point in the script. Up until that point, the object doesn't need to exist. If the object was a global variable instead, either it would have to already exist, or the code trying to reference the object would first need to instantiate it. In fact, anywhere that it could be used, it would need to be instantiated correctly. By centralizing the creation of the single object in getInstance, you avoid having to create copy-and-paste boilerplate every time you need to reference the object.

Database objects usually get created very early on in the request lifetime, so that specific benefit of Singleton-ness would be wasted.

There are other alternatives to Singleton that can get the job done in other ways. One example is dependency injection, a fancy term for passing external objects that a new object would depend on (such as a database handle) to the object at construction time. However, this can be complicated or annoying. Doing it right might involve injecting a lot of the same objects every single time.

Another alternative is the Registry pattern, which is effectively a container for things that would otherwise be globals. If you don't like global variables, but don't mind them being effectively namespaced, this would be a solution that you'd like.

In the end, pick one way to do it, and stick with that one way throughout your codebase. Personally, I'm a fan of the database object being a global.

Upvotes: 8

Related Questions