Globally available database connection without using Global/Singleton - php

I'm creating a new PHP application and want to make sure I get the ground work right to save any future problems. I know my application will have more than one class that will need a database connection (PDO) and after a long time scouring the internet i can't find a definitive solution.
I like the singleton design pattern personally, but there are a lot of people out there that say singletons in general should be avoided at all costs. These people, however, don't give a specific solution to this problem.
I understand that an application may need more than one database connection but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
Is it a case of having to pass round the PDO (or PDO wrapper) object to every class that may need it? I've done this before found it annoying keeping track of it.

I personally thing a singleton (or a multiton, if you need several DB connections) is fine for such an usage.
But if you do not want to use it, you should then take a look at the Registry pattern.
This way, you can have your database class instance(s) available for all your application's classes, without having to pass an additional parameter each time (which is very ugly, IMHO).

but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
you can, it's called multiton pattern

Related

How to use DAL on PHP

Hello i have a code where they use this to connect to database
$db= DAL::get_instance();
$count=$db->read_single_column("select count(id) from ".TABLE_PREFIX."users where email=? and status=1", array($email));
echo "Aqui".$count;
I make a blank new page for that site, but i think $db= DAL::get_instance(); is not working.. i dont want to create multiple Connections to database, so how can i use DAL on PHP so i can use that same chain to connect...
And where and how is set DAL? (how can i search for the string where is set, whats the format)
Thanks
I Found a DAL.php on the library core.. But its encripted with Ioncube.. so my guess is i wont be able to see how is set :(
Your DAL class is userland-defined - there is no such thing in PHP. Post the entire code of it somewhere and someone might be able to tell you what to do with it.
I will, however, provide generics based on what you've said. static::get_instance() and the mention that you are not able to fire more than one instance of it suggests that your database abstraction layer is, in fact, a Singleton. This is good, and then again, this is very bad. The entire aim of the Singleton is to restrict the class to one and one instance only, which is quite nice for a database layer.
In your case, however, it looks like you want to connect to multiple DBs at the same time. Depending on how the code is coded, you may be able to do this with little to no modification to the code.
For reference, this is a simplified version of your DAL: http://codepad.viper-7.com/gPQ8bo . I kept the bits you are concerned with and stripped everything else out.
The obvious way
Rip up the singleton and start using dependency injection.
The not-so-obvious way
You can use Reflection to reset a Singleton's private static member. This is a hack, so use only if you have to.
The fiddle to this lies here: http://codepad.viper-7.com/ja6zHL . The code is as follows:
$reflection = new \ReflectionProperty('MySingleton', 'instance'); // Get a handle to the private self::$instance property
$reflection->setAccessible(true); // Set it to public
$reflection->setValue(null, null); // Modify it
// Optional: re-restrict it
$reflection->setAccessible(false);
Note that this is hackish for three reasons:
You should not be doing this. Instead, you should consider using a DAL that actually allows you to fire multiple connections or make one yourself
This uses Reflection, which has pretty big performance implications
This is a hack. You also lose your first DB connection, so you need extra housekeeping.

Advice on database connection within PHP class

I am playing around with OOP programming, and have hit a hurdle I could use advice with.
I have a situation where I have nested classes. I have a "Company" class, which contains an array called people. This array contains many instances of a "Person" class.
The data for both 'company' and 'person', are stored within a database, and the relevant class retrieves the information from that database as and when it is needed.
My question quite simply is this: "At what point do I connect to the database?" Do I:-
a) Connect first in my PHP page, then pass the connection to the instance of "Company" for it to use.
b) Put the username, password etc directly in the "Company" class and connect there.
I would have thought that the latter would create multiple connections to the database - one for each instance of "Company" - so probably the answer is "A". But then, if I were to pass the class to another developer (this is only a learning exercise, so not something I plan to do), he would have to connect to the database himself, and not allow my class to do it for him.
In either case, would the connection be passed to each instance of the "Person" class automatically, or would I have to pass the connection each time I create a new instance?
I have done some research on this, and I think the answer is "A" (connect to the database in my PHP page, and pass the connection to each instance of the Company class), but just thought I should double check before I get too far.
Thanks for any advice you are able to offer.
You solution A) sounds familiar to me. That way you can just pass the database connection to the object or maintain a global registry to store the connection object (e.g. PDO) into.
I think you're on the right track.
What you're describing is known as dependency injection and using it is generally a good idea.
When you're dealing with a more complex project, it might be a good idea to abstract the retrieval of data completely. Create an interface, i.e. "PersonFinder" or "CompanyFinder" that deals only with the lookup and retrieval of its associated records. Concrete implementations of this interface might include database lookups, or CSV file lookups, or even some sort of web-based service lookup. Pass your Finder into your Company or Person objects when you create them.
This way you can easily change how you find your records without changing the code that deals with them.

The best way to ensure staticness in PHP?

I've got this Config-class that I use in my PHP5 application to load & parse my static config. This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
But now as I need to set/make changes in my Config during runtime at one place, my changes aren't reflected globally and being far from a specialist with the use of the static modifier in PHP, I need to ask:
What is the best way to ensure that changes to the properties in my Config-class are reflected throughout my application without making the class into a singleton? Can I just make the variable holding the config data static?
This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
If you pass the same instance of your Config class to every part of your application and you change a setting it should be reflected everywhere else.
In case you are creating multiple objects of the class (and parse that config file every time?!) you might want to stop doing that. It's possibly wasteful and I'd say it is confusing.
So if you create only one and pass that around everything should be fine.
Under the assumption that you create multiple instances of the object that only should exist once:
If you are able to "fix" your architecture to allow you to do that: Do so.
If you can't to that... well.. creating a static property to hold your values in a class that you can have multiple instances off is, at least in my book, a major wtf factor. If you can't fix (meaning it's to much off a hassle to do so) just "break" it in an expected way so other people don't trip over it.
I'd rather have a singleton than something that creates all the issues with singletons and also lies about being a wrapper for a global variable.
Blindly avoiding design patterns because you hear on Internet forums that they're bad is about as much an anti-pattern as singletons are in general. If a tool is right for a job, then it's right.
Look at your question, you're trying to emulate singletons through a complex multi-update system for God's sakes... And just so you know, making a class static is essentially turning it into a singleton, albeit an insecure one that can be overwritten at any time.
TL;DR: Think for yourself and use the right tools; make your config class a singleton.

Is there a use-case for singletons with database access in PHP?

I access my MySQL database via PDO. I'm setting up access to the database, and my first attempt was to use the following:
The first thing I thought of is global:
$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');
function some_function() {
global $db;
$db->query('...');
}
This is considered a bad practice. After a little search, I ended up with the Singleton pattern, which
"applies to situations in which there needs to be a single instance of a class."
According to the example in the manual, we should do this:
class Database {
private static $instance, $db;
private function __construct(){}
static function singleton() {
if(!isset(self::$instance))
self::$instance = new __CLASS__;
return self:$instance;
}
function get() {
if(!isset(self::$db))
self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')
return self::$db;
}
}
function some_function() {
$db = Database::singleton();
$db->get()->query('...');
}
some_function();
Why do I need that relatively large class when I can do this?
class Database {
private static $db;
private function __construct(){}
static function get() {
if(!isset(self::$db))
self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');
return self::$db;
}
}
function some_function() {
Database::get()->query('...');
}
some_function();
This last one works perfectly and I don't need to worry about $db anymore.
How can I create a smaller singleton class, or is there a use-case for singletons that I'm missing in PHP?
Singletons have very little - if not to say no - use in PHP.
In languages where objects live in shared memory, Singletons can be used to keep memory usage low. Instead of creating two objects, you reference an existing instance from the globally shared application memory. In PHP there is no such application memory. A Singleton created in one Request lives for exactly that request. A Singleton created in another Request done at the same time is still a completely different instance. Thus, one of the two main purposes of a Singleton is not applicable here.
In addition, many of the objects that can conceptually exist only once in your application do not necessarily require a language mechanism to enforce this. If you need only one instance, then don't instantiate another. It's only when you may have no other instance, e.g. when kittens die when you create a second instance, that you might have a valid Use Case for a Singleton.
The other purpose would be to have a global access point to an instance within the same Request. While this might sound desirable, it really isnt, because it creates coupling to the global scope (like any globals and statics). This makes Unit-Testing harder and your application in general less maintainable. There is ways to mitigate this, but in general, if you need to have the same instance in many classes, use Dependency Injection.
See my slides for Singletons in PHP - Why they are bad and how you can eliminate them from your applications for additional information.
Even Erich Gamma, one of the Singleton pattern's inventors, doubts this pattern nowadays:
"I'm in favor of dropping Singleton. Its use is almost always a design smell"
Further reading
How is testing the registry pattern or singleton hard in PHP?
What are the disadvantages of using a PHP database class as a singleton?
Database abstraction class design using PHP PDO
Would singleton be a good design pattern for a microblogging site?
Modifying a class to encapsulate instead of inherit
How to access an object from another class?
Why Singletons have no use in PHP
The Clean Code Talks - Singletons and Global State
If, after the above, you still need help deciding:
Okay, I wondered over that one for a while when I first started my career. Implemented it different ways and came up with two reasons to choose not to use static classes, but they are pretty big ones.
One is that you will find that very often something that you are absolutely sure that you'll never have more than one instance of, you eventually have a second. You may end up with a second monitor, a second database, a second server--whatever.
When this happens, if you have used a static class you're in for a much worse refactor than if you had used a singleton. A singleton is an iffy pattern in itself, but it converts fairly easily to an intelligent factory pattern--can even be converted to use dependency injection without too much trouble. For instance, if your singleton is gotten through getInstance(), you can pretty easily change that to getInstance(databaseName) and allow for multiple databases--no other code changes.
The second issue is testing (And honestly, this is the same as the first issue). Sometimes you want to replace your database with a mock database. In effect this is a second instance of the database object. This is much harder to do with static classes than it is with a singleton, you only have to mock out the getInstance() method, not every single method in a static class (which in some languages can be very difficult).
It really comes down to habits--and when people say "Globals" are bad, they have very good reasons to say so, but it may not always be obvious until you've hit the problem yourself.
The best thing you can do is ask (like you did) then make a choice and observe the ramifications of your decision. Having the knowledge to interpret your code's evolution over time is much more important than doing it right in the first place.
Who needs singletons in PHP?
Notice that almost all of the objections to singletons come from technical standpoints - but they are also VERY limited in their scope. Especially for PHP. First, I will list some of the reasons for using singletons, and then I will analyze the objections to usage of singletons. First, people who need them:
- People who are coding a large framework/codebase, which will be used in many different environments, will have to work with previously existing, different frameworks/codebases, with the necessity of implementing many different, changing, even whimsical requests from clients/bosses/management/unit leaders do.
See, the singleton pattern is self inclusive. When done, a singleton class is rigid across any code you include it in, and it acts exactly like how you created its methods and variables. And it is always the same object in a given request. Since it cannot be created twice to be two different objects, you know what a singleton object is at any given point in a code - even if the singleton is inserted to two, three different, old, even spaghetti codebases. Therefore, it makes it easier in terms of development purposes - even if there are many people working in that project, when you see a singleton being initialized in one point in any given codebase, you know what it is, what it does, how it does, and the state it is in. If it was the traditional class, you would need to keep track of where was that object first created, what methods were invoked in it until that point in the code, and its particular state. But, drop a singleton there, and if you dropped proper debugging and information methods and tracking into the singleton while coding it, you know exactly what it is. So therefore, it makes it easier for people who have to work with differing codebases, with the necessity of integrating code which was done earlier with different philosophies, or done by people who you have no contact with. (that is, vendor-project-company-whatever is there no more, no support nothing).
- People who need to work with third-party APIs, services and websites.
If you look closer, this is not too different than the earlier case - third-party APIs, services, websites, are just like external, isolated codebases over which you have NO control. Anything can happen. So, with a singleton session/user class, you can manage ANY kind of session/authorization implementation from third-party providers like OpenID, Facebook, Twitter and many more - and you can do these ALL at the same time from the SAME singleton object - which is easily accessible, in a known state at any given point in whatever code you plug it into. You can even create multiple sessions to multiple different, third-party APIs/services for the SAME user in your own website/application, and do whatever you want to do with them.
Of course, all of this also can be tone with traditional methods by using normal classes and objects - the catch here is, singleton is tidier, neater and therefore because of that manageable/testable easier compared to traditional class/object usage in such situations.
- People who need to do rapid development
The global-like behavior of singletons make it easier to build any kind of code with a framework which has a collection of singletons to build on, because once you construct your singleton classes well, the established, mature and set methods will be easily available and usable anywhere, anytime, in a consistent fashion. It takes some time to mature your classes, but after that, they are rock solid and consistent, and useful. You can have as many methods in a singleton doing whatever you want, and, though this may increase the memory footprint of the object, it brings much more savings in time required for rapid development - a method you are not using in one given instance of an application can be used in another integrated one, and you can just slap a new feature which client/boss/project manager asks just by a few modifications.
You get the idea. Now lets move on to the objections to singletons and
the unholy crusade against something that is useful:
- Foremost objection is that it makes testing harder.
And really, it does to some extent, even if it can be easily mitigated by taking proper precautions and coding debugging routines into your singletons WITH the realization that you will be debugging a singleton. But see, this isnt too different than ANY other coding philosophy/method/pattern that is out there - it's just that, singletons are relatively new and not widespread, so the current testing methods are ending up comparably incompatible with them. But that is not different in any aspect of programming languages - different styles require different approaches.
One point this objection falls flat in that, it ignores the fact that the reasons applications developed is not for 'testing', and testing is not the only phase/process that goes into an application development. Applications are developed for production use. And as I explained in the 'who needs singletons' section, singletons can cut a GREAT deal from the complexity of having to make a code work WITH and INSIDE many different codebases/applications/third-party services. The time which may be lost in testing, is time gained in development and deployment. This is especially useful in this era of third-party authentication/application/integration - Facebook, Twitter, OpenID, many more and who knows what's next.
Though it is understandable - programmers work in very different circumstances depending on their career. And for people who work in relatively big companies with defined departments tending different, defined software/applications in a comfortable fashion and without the impending doom of budget cuts/layoffs and the accompanying need to do a LOT of stuff with a lot of different stuff in a cheap/fast/reliable fashion, singletons may not seem so necessary. And it may even be nuisance/impediment to what they ALREADY have.
But for those who needs to work in the dirty trenches of 'agile' development, having to implement many different requests (sometimes unreasonable) from their client/manager/project, singletons are a saving grace due to reasons explained earlier.
- Another objection is that its memory footprint is higher
Because a new singleton will exist for each request from each client, this MAY be an objection for PHP. With badly constructed and used singletons, the memory footprint of an application can be higher if many users are served by the application at any given point.
Though, this is valid for ANY kind of approach you can take while coding things. The questions which should be asked are, are the methods, data which are held and processed by these singletons unnecessary? For, if they ARE necessary across many of the requests application is getting, then even if you don't use singletons, those methods and data WILL be present in your application in some form or another through the code. So, it all becomes a question of how much memory will you be saving, when you initialize a traditional class object 1/3 into the code processing, and destroy it 3/4 into it.
See, when put this way, the question becomes quite irrelevant - there should not be unnecessary methods, data held in objects in your code ANYway - regardless of you use singletons or not. So, this objection to singletons becomes really hilarious in that, it ASSUMES that there will be unnecessary methods, data in the objects created from the classes you use.
- Some invalid objections like 'makes maintaining multiple database connnections impossible/harder'
I can't even begin to comprehend this objection, when all one needs to maintain multiple database connections, multiple database selections, multiple database queries, multiple result sets in a given singleton is just keeping them in variables/arrays in the singleton as long as they are needed. This can be as simple as keeping them in arrays, though you can invent whatever method you want to use to effect that. But let's examine the simplest case, use of variables and arrays in a given singleton:
Imagine the below is inside a given database singleton:
$this->connections = array(); (wrong syntax, I just typed it like this to give you the picture - the proper declaration of the variable is public $connections = array(); and its usage is $this->connections['connectionkey'] naturally )
You can set up, and keep multiple connections at any given time in an array in this fashion. And same goes for queries, result sets and so forth.
$this->query(QUERYSTRING,'queryname',$this->connections['particulrconnection']);
Which can just do a query to a selected database with a selected connection, and just store in your
$this->results
array with the key 'queryname'. Of course, you will need to have your query method coded for this - which is trivial to do.
This enables you to maintain a virtually infinite number of (as much as the resource limits allow of course) different database connections and result sets as much as you need them. And they are available to ANY piece of code in any given point in any given codebase into which this singleton class has been instantiated.
OF COURSE, you would naturally need to free the result sets, and connections when not needed - but that goes without saying, and it's not specific to singletons or any other coding method/style/concept.
At this point, you can see how you can maintain multiple connections/states to third-party applications or services in the same singleton. Not so different.
Long story short, in the end, singleton patterns are just another method/style/philosophy to program with, and they are as useful as ANY other when they are used in the correct place, in the correct fashion. Which is not different from anything.
You will notice that in most of the articles in which singletons are bashed, you will also see references to 'globals' being 'evil'.
Let's face it - ANYthing that is not used properly, abused, misused, IS evil. That is not limited to any language, any coding concept, any method. Whenever you see someone issuing blanket statements like 'X is evil', run away from that article. Chances are very high that it's the product of a limited viewpoint - even if the viewpoint is the result of years of experience in something particular - which generally ends up being the result of working too much in a given style/method - typical intellectual conservatism.
Endless examples can be given for that, ranging from 'globals are evil' to 'iframes are evil'. Back around 10 years ago, even proposing the use of an iframe in any given application was heresy. Then comes Facebook, iframes everywhere, and look what has happened - iframes are not so evil anymore.
There are still people who stubbornly insist that they are 'evil' - and sometimes for good reason too - but, as you can see, there is a need, iframes fill that need and work well, and therefore the entire world just moves on.
The foremost asset of a programmer/coder/software engineer is a free, open and flexible mind.
Singletons are considered by many to be anti-patterns as they're really just glorified global variables. In practice there are relatively few scenarios where it's necessary for a class to have only one instance; usually it's just that one instance is sufficient, in which case implementing it as a singleton is completely unnecessary.
To answer the question, you're right that singletons are overkill here. A simple variable or function will do. A better (more robust) approach, however, would be to use dependency injection to remove the need for global variables altogether.
In your example you're dealing with a single piece of seemingly unchanging information. For this example a Singleton would be overkill and just using a static function in a class will do just fine.
More thoughts: You might be experiencing a case of implementing patterns for the sake of patterns and your gut is telling you "no, you don't have to" for the reasons you spelled out.
BUT: We have no idea of the size and scope of your project. If this is simple code, perhaps throw away, that isn't likely to need to change then yes, go ahead and use static members. But, if you think that your project might need to scale or be prepped for maintenance coding down the road then, yes, you might want to use the Singleton pattern.
First, I just want to say that I don't find much uses to the Singleton pattern. Why would one want to keep a single object thorough the whole application? Especially for databases, what if I want to connect to another database server? I have to disconnect and reconnect every time...? Anyway...
There are several drawbacks to using globals in an application (which is what the traditional use of the Singleton pattern does):
Difficult to unit test
Dependency injection issues
Can create locking issues (multi-threaded application)
Use static classes instead of a singleton instance provides some of the same drawbacks as well, because the biggest problem of singleton is the static getInstance method.
You can limit the number of instances a class can have without using the traditional getInstance method:
class Single {
static private $_instance = false;
public function __construct() {
if (self::$_instance)
throw new RuntimeException('An instance of '.__CLASS__.' already exists');
self::$_instance = true;
}
private function __clone() {
throw new RuntimeException('Cannot clone a singleton class');
}
public function __destruct() {
self::$_instance = false;
}
}
$a = new Single;
$b = new Single; // error
$b = clone($a); // error
unset($a);
$b = new Single; // works
This will help on the first the points mentioned above: unit testing and dependency injection; while still making sure a single instance of the class exist in your application. You could, per example, just pass the resulting object to your models (MVC pattern) for them to use.
Consider simply how your solution differs from the one presented in the PHP docs. In fact, there is just one "small" difference: your solution provides callers of the getter with a PDO instance, while the one in the docs provides callers of Database::singleton with a Database instance (they then use the getter on that to get a PDO instance).
So what conclusion do we reach?
In the documentation code, callers get a Database instance. The Database class may expose (in fact, it should expose if you 're going to all this trouble) a richer or higher-level interface than the PDO object it wraps.
If you change your implementation to return another (richer) type than PDO, then the two implementations are equivalent. There's no gain to be had from following the manual implementation.
On the practical side, Singleton is a pretty controversial pattern. This is mainly because:
It's overused. Novice programmers grok Singleton much easier than they grok other patterns. They then go on to apply their newfound knowledge everywhere, even if the problem at hand can be solved better without Singleton (when you 're holding a hammer, everything looks like a nail).
Depending on the programming language, implementing a Singleton in an airtight, non-leaky manner can prove to be a titanic task (especially if we have advanced scenarios: a singleton depending on another singleton, singletons that can be destroyed and re-created, etc). Just try to search for "the definitive" Singleton implementation in C++, I dare you (I own Andrei Alexandrescu's groundbreaking Modern C++ Design, which documents much of the mess).
It imposes additional workload both when coding the Singleton and when writing code to access it, workload which you can do without by following a few self-imposed constraints on what you try to do with your program variables.
So, as a final conclusion: your singleton is just fine. Not using Singleton at all is just fine most of the time as well.
Your interpretation is correct. Singletons have their place but are overused. Often, accessing static member functions is sufficient (notably, when you do not need to control time-of-construction in any way). Better, you can just put some free functions and variables in a namespace.
When programming there is not "right" and "wrong"; there is "good practice" and "bad practice".
Singletons are generally created as a class to be reused later. They need to be created in such a way that the programmer doesn't accidentally instantiate two instances while drunkenly coding at midnight.
If you have a simple little class that shouldn't be instantiated more than once, you don't need to make it a singleton. It's just a safety net if you do.
it's not always bad practice to have global objects. If you know that you're going to use it globally/everywhere/all the time, it may be one of the few exceptions. However, globals are generally considered "bad practice" in the same way that goto is considered bad practice.
I don't see any point to this at all. If you implemented the class in such a way that the connection string was taken as a parameter to the constructor and maintained a list of PDO objects (one for each unique connection string) then maybe there would be some benefit, but the implementation of singleton in this instance seems like a pointless exercise.
You are not missing anything, as far as I can see. The example is pretty flawed.
It would make difference, if the singleton class had some non-static instance variables.

What are the disadvantages of using a PHP database class as a singleton?

What are the disadvantages of using a PHP database class as a singleton?
The disadvantages are the same as for any class that uses the Singleton pattern:
It is hard to test code that uses singletons.
If your DB class is built to only connect to a single database, you will have problems when you have a script that needs to connect to 2 two separate databases. However, you could build the singleton class to accept multiple server configurations, and then manage them within the singleton.
Otherwise, designing a database class as a singleton is a practice that makes a lot of sense, as you can maintain tight control over how many connections a script is making at any given time.
You can not use two database connections. You would want this because:
you have two databases.
you want to do something within a transaction when another transaction is already running on the 'current' database connection.
you want to use several mock database instances in your unit tests
It makes it hard to run unit tests against it and also makes it impossible to have multiple database connections. As we all know, global variables has lots of drawbacks and Singletons are no exception, only that they are a more "friendly" global variable.
I found a pretty good article about it and an old SO question as well.

Categories