views:

126

answers:

2

I have a set of static class methods. I also have an existing database connection in a script stored in an object variable $DB. How do I call those static class methods and let them use that $DB object without having to pass them this variable every time as a parameter on the class method?

For instance, right now I'm having to use a global, unfortunately:

class Foo {
  public static function Bar() {
    global $DB;
    return $DB->DSN_STRING;
  }
}

It's like I need my static class to call itself with a routine that somehow gets the $DB connection without having to re-establish it. Note I can't inject it into the static class because it's not instantiated.

Of course the problem is solved if I switch from a static class to a regular class and instantiate my $Foo object. I could then inject the $DB var as a setting on a public variable. Or add a public method to receive the $DB var and then set a private var of the $Foo object. Or, make a class constructor accept the $DB var and set a private var of the $Foo object. But all 3 techniques require that I switch from a static class to a regular class.

Some people have mentioned something called a Registry pattern or a Singleton pattern (I think it's the same thing? Not sure). Is this what I need to resolve this problem efficiently?

The thing most of all is that I avoid calling "global $DB" because people freak out about that.

+1  A: 

I think a Singleton would work well for what you're trying to do. Otherwise you're restricted to having to use the 'global' keyword which, as you've found out already, is extremely expensive.

Darrell Brogdon
Good. I'm on the right track. Can you give me an example?
Volomike
+5  A: 

I would, and do, use the singleton pattern for this. I utilize a class that I'll just call Database_Manager here:

class Database_Manager
{
    private static $instance;
    private $db_connection;

    public static function getInstance()
    {
     if (self::$instance == null) {
      $className = __CLASS__;
      self::$instance = new $className();
     }
     return self::$instance;
    }

    public static function initializeConnection($connectionInfo)
    {
     $db = self::getInstance();
     //call init functions.. connect to db, etc
            //save connection to $db->db_connection;

    }

    public static function getDb()
    {
     $db = self::getInstance();
     return $db->db_connection;
    }
}

You can set things up once with the initializeConnection() call, and then just call Database_Manager::getDb() from then on out.

The nice thing about this approach is it is easily modified to manage connections to multiple databases, and you're guaranteed to only ever have one open connection per database.

Note that I left out some of the nitty-gritty of the Singleton implementation, such as declaring the __construct() function private (most of that above is copied from memory). I just wanted to show the overall approach.

zombat
This was *EXACTLY* what I needed, and I didn't realize a static class could maintain an object persistence inside it.
Volomike
Good times with Singletons. :) Glad to be of help.
zombat