(PHP) Класс базы данных Singleton - как насчет статических методов? - PullRequest
3 голосов
/ 28 декабря 2011

Это базовый сайт. Основываясь на ответах здесь, я делаю это:

private $db;

public function __construct($id = null) {
    $this->db = Db::getInstance(); //singleton from the Db class

Но если есть статический метод, я не могу использовать переменную, специфичную для объекта.

Есть ли что-то лучше, чем указывать переменную db внутри статического метода вручную?

public static function someFunction($theID){
    $db = Db::getInstance();

РЕДАКТИРОВАТЬ: Создание статической переменной не решает проблему. Access to undeclared static property. Я все еще должен был бы назначить переменную в статической функции. Вопрос в том, есть ли способ обойти это.

Мой класс БД (хотя это и не важно для этого обсуждения):

class Db {
private static $m_pInstance;
private function __construct() { ... }

public static function getInstance(){
    if (!self::$m_pInstance)
        self::$m_pInstance = new Db();
    return self::$m_pInstance;
}

}

Ответы [ 2 ]

5 голосов
/ 28 декабря 2011

Да, вы можете сделать $db статическим:

static private $db;

Я предполагаю, что это то, что вам нужно, так как вы получаете доступ к нему из метода static.Если есть какая-то причина, по которой вы этого не хотите, это должно означать, что метод, вероятно, не должен быть static.

РЕДАКТИРОВАТЬ:

Согласно комментариям @zerkms (спасибо),вы получаете доступ к статическим переменным с помощью self:::

self::$db = Db::getInstance(); 
3 голосов
/ 28 декабря 2011

Вы обрисовали одну из проблем, с которой вы сталкиваетесь, когда смешиваете статические методы в классе, который также может быть очищен, устанавливаете переменные-члены посредством создания экземпляров и ожидаете доступ к их значениям через вызов статического метода. Единственный реальный способ обойти это - установить специфичный для класса синглтон для синглтона базы данных или передать объект DB статическому методу.

// Option 1
class MyClass
{
    private static $db;

    public function __construct($id = null)
    {
        self::$db = Db::getInstance(); //singleton from the Db class
    }

    public static function someFunction($theID)
    {
        self::$db->query('SELECT * FROM my_table');    
    }
}

// Singleton DB for MyClass will be initalized via constructor
$myClass = new MyClass();    

// This call will have access to DB object set via class specific singleton
MyClass::someFunction(4);

// Option 2
class MyClass
{
    private $db;

    public function __construct($id = null)
    {
        $this->$db = Db::getInstance(); //singleton from the Db class

        if (!is_null($id)) {
            $this->id = $id;
        }
    }

    public function getDb()
    {
        return $this->db;
    }

    public function getId()
    {
        return $this->id;
    }

    // Sub-Option 1: If Id ISNT set via object
    public static function someFunction($object, $theID)
    {
        $object->getDb()->query('SELECT * FROM my_table WHERE id = ' . (int) $theID);    
    }

    // Sub-Option 2: If Id IS set via object
    public static function someFunction($object)
    {
        $object->getDb()->query('SELECT * FROM my_table WHERE id = ' . (int) $object->getId());    
    }
}

// Sub-Option 1 call
$myClass = new MyClass();

MyClass::someFunction($myClass, 4);

// Sub-Option 2 call
$myClass = new MyClass(4);

MyClass::someFunction($myclass);
...