English 中文(简体)
PHP: How to pass existing database connection to static class methods?
原标题:

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.

最佳回答

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.

问题回答

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.





相关问题
Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

JSON with classes?

Is there a standardized way to store classes in JSON, and then converting them back into classes again from a string? For example, I might have an array of objects of type Questions. I d like to ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Passing another class amongst instances

I was wondering what is the best practice re. passing (another class) amongst two instances of the same class (lets call this Primary ). So, essentially in the constructor for the first, i can ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签