(PHP)单例数据库类——静态方法呢?


(PHP) Singleton Database Class - what about static methods?

这是一个基本的网站。根据这里的答案,我这样做:

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。我仍然需要在静态函数中分配变量。问题是问是否有办法解决这个问题。

我的DB类(尽管对本次讨论不重要):

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;
}

}

是的,您可以将$db设置为静态的:

static private $db;

我假设这是你需要的,因为你从static方法访问它。如果有任何理由不希望这样做,那一定意味着该方法可能不应该是static

编辑:

根据@zerkms(谢谢)评论,您可以使用self::访问静态变量:

self::$db = Db::getInstance(); 

您已经概述了在可以实例化的类中混合静态方法、通过实例化设置成员变量并期望通过静态方法调用访问它们的值时遇到的一个问题。真正解决这个问题的唯一方法是为数据库的单例设置一个特定于类的单例,或者将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);