Passing DB object around

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Passing DB object around

Post by Ree »

Which do you recommend - using singleton to create/return the db object, or just passing it to all classes? The first approach would make my life a bit easier but that's global stuff. The second approach, as I understand, is the preferable one, but it forces me to also pass the db object to the classes which extend other classes, which I do not like that much. Which way is a better one in your opinion? Which is considered better when used together with unit testing?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

It sounds like you've already made your decision, so run with it.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post by Ree »

Well, I haven't yet, that's why I'm asking for recommendations.
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

Marcus Baker wrote a really good article on this a while back in the php|architect magazine. He elaborated many different options (his article was generic to any dependant object, but certainly applies to a database object).

Among the options are:

1) always create new by hand
2) always create from a factory
3) use a global variable :evil:
4) use a singleton (stealth global)
5) use a registry (reference hiding in a stealth global)
6) pass it in to the constructor
7) have a setter method to set it after creation
8 ) use 6 or 7 in combination with a Dependancy Injection framework

I am sure I have forgotten several of the originally listed options, but I think you get the picture.

One technique I have used on a reasonable number of small scripts it to combine 2 and 7. This allows me to default the database connection in most instances, but allows for overriding that default when I want to (for instance, during unit testing).

HTH
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

It depends (for me at least). If the DB object is getting used in background (say a Data Access layer) I'll try to pass it as a parameter to the constructor. If its being used for some reason upfront (a lot) I'll consider a singleton, esp. if it starts looking like the parameter method is being thoroughly overused which is annoying because I hate clogging up the parameter list.

Passing to a constructor (sweatje's method) is usually fairly good for most cases. A lot depends on how your client code (what actually does actions) handles object creation - is it there and then, or handled by an include?
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Passing the db construct in and using a singleton both imply that the mechanism in need of this constructs services know it's interface. If that's the case, why not make the construct aware of a factory and be done with it. If your objects are working together this closely, why not let them also take care of certain thing you may otherwise hack out by hand?
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

BDKR wrote:Passing the db construct in and using a singleton both imply that the mechanism in need of this constructs services know it's interface. If that's the case, why not make the construct aware of a factory and be done with it. If your objects are working together this closely, why not let them also take care of certain thing you may otherwise hack out by hand?
How do you then substitute in a mock object for testing if you have hard coded the construction dependancy?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Loose wiring? :)

Code: Select all

function constructor(&$db) {
    if(!is_object($db))
    {
        $this->db =& AppHelper::getDB(); // in app
    }
    else
    {
        $this->db = $db; // for unit testing
    }
}
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

Maugrim_The_Reaper wrote:Loose wiring? :)
Essentially what I recomended in my first post as " combine 2 and 7" except yours is "combine 2 and optional 6". The only issue there is PHP4 optional objects by reference are tricky.

See http://blog.casey-sweat.us/?p=14
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

You're right - I keep forgetting those niggling issues with < &var='' >.... :roll: Stupid of me.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

sweatje wrote: How do you then substitute in a mock object for testing if you have hard coded the construction dependancy?
The bull**** answer:
; ksudif9q[3[4j1cl ;nc[90zayu fr9[c4rlasd98uq389-4yu pcbi cvh 8aeh 45 a;9r8vu9-3q4un ;kbuiuvu8pd7 yhr9af

The real answer:
Not being someone big on this form of testing, I'd have to say that's a good question to wich I don't have an answer. LOL!

However, I'm all ears. :)

Let me also add something else. Part of my original point is, however unspoken, that if the various objects being used are aware
of the db object interface, then they are part of a loose framework of sorts. My contention is that if it's gotten that far, let those
individual objects pass their own messages back the factory when they need handles to objects.

Of course, the more I think about it, I can see how it can make testing using mock objects difficult.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Phppatterns is back online: Marcus Baker's article on the Registry makes an interesting read - and includes some discussion on how to write a test-able Registry.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

McGruff wrote:Phppatterns is back online: Marcus Baker's article on the Registry makes an interesting read - and includes some discussion on how to write a test-able Registry.
LOL! It's funny because I realized after reading his article that my factory class is also acting as a registry class.
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

In my book I talk about that very concept. Registry is a wonderful pattern to embed inside a parameterized Factory.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

I'm going to have to make a point of reading your book. :D
Post Reply