NogDog;11061427 wrote:I've always assumed that, since PHP is (usually) not multi-threaded, a single connection would be at least somewhat more efficient -- but I've never measured it. Whether you want/need a singleton class for that is optional, vs. just having one PDO or whatever object created in your initial config or such, and then pass it in to each thing that needs it. But if you want to apply it to existing code, a Singleton might be a good way to do it with minimal impact on the code base, if it's already using some common DB class?
Thanks for getting the meeting started. I'll sit in the corner sucking my thumb while we discuss this, and you'll see why in a moment.
Weedpacket;11061437 wrote:I have occasionally needed multiple DB connections (database migration; having to build an app-specific database so that the main db wouldn't get "contaminated" by the app's lookup table requirements or vice versa; or simply having to live with the fact that I had to connect to two different databases from different providers).
But I'd only want a single connection to each. I'm not sure how one PHP instance would handle two connection requests with the same credentials - whether they'd result in two connections or return the first connection for the second request - but the DBMS itself would create two distinct connections and stuff going on in one connection won't be visible in the other until the transactions commit. Fixing a bug from that would be like looking at a "spot-the-difference" puzzle: cross your eyes so the two pictures are in register and then look for the bits where your focus tries to fight back.
Putting those together I'd be inclined to make the Singleton a Factory (while still being a Singleton). It keeps a collection of which database connections have been made, and responds with existing ones when additional requests for them come through.
Note that disconnections have to pass through the factory/singleton as well, and if you really want the disconnection to happen the factory will need to at least keep a reference count of the number of times the connection has been requested. With a single connection, no-one using it could have the authority to close it in ignorance of who else might still be using it.
I have one app that has multiple DB connections. I'm not looking at it right now (it's Sunday evening here, so one good question might be what the heck am I doing on PHPBuilder, anyway? 😉) IIRC though, it does have a Singleton DB class and two subclasses for the other two connections, so I can call "MainDB::getInstance()", "RemoteDB::getInstance()", etc.
Now, here's the thing I'm in the corner stimming over (is that what the shrinks call it?). I've had this class sitting there for a Long Time, and the notes say it didn't work with the classes that called it, causing errors of the "cannot connect to DB" type. I was running through the classes for this app the other day and happened to open this one and found a bug. Ran a quick test and it seemed OK, so I inserted it into a Very Important Class and ran the live page on the production site; no detectable errors, page looks fine. Happy Dale 😃
So, how were the other classes all doing their DB stuff? Each one had a getDB() method which wrapped a connection call. So, for a script that had a Page class, a User class, a Product class, a Seller class, and a Category class, one call to the app was using 5 DB connections, ostensibly. (But, as you point out .... maybe not?) What I'm really curious about is if having them all access the Singleton will reduce DB server load.
Derokorian;11061443 wrote:I use singleton connections, and what that means is my class holds an array of named connections - this way I can still easily have an arbitrary number of DB connections (maybe separate read and write, and maybe another for session, and whatever)
That's interesting. As I mentioned above, I've had success with a master class and subclasses for the other DB's ... that might be another valid way to skin the cat? Or what you might be saying here is that you can give a particular script as few or as many connections as you want, which might be something worth looking into, although unless you're running threads (which I've done but not frequently), I'm not sure how that would benefit us?