【问题标题】:(PHP) Singleton Database Class - what about static methods?(PHP) 单例数据库类 - 静态方法呢?
【发布时间】:2011-12-28 00:15:11
【问题描述】:

这是一个基本的网站。根据此处的答案,我正在这样做:

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

}

【问题讨论】:

  • 有什么原因不能在someFunction 中使用$this->db?为什么还要在构造函数中设置它?
  • 不要使用静态方法
  • @DaOgre: someFunction 是静态的
  • 仅供参考:Db::getInstance() 不是单例,它是一个工厂,它返回一个单例。
  • @Digital Precision:你为什么这么认为?此外,还有 2 种不同的 工厂模式。你提到的是哪一个?

标签: php database variables static singleton


【解决方案1】:

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

static private $db;

我假设这就是您所需要的,因为您是通过 static 方法访问它的。如果有任何理由不想要这个,那一定意味着该方法可能不应该是static

编辑:

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

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

【讨论】:

  • ... 但这会引发严格的标准违规通知。不酷
  • @zerkms 我不确定我理解你的意思。你是说静电不好?静态是 OO 设计的一部分。
  • ideone.com/aupWx。 Java、c# 等不允许您使用 this 实例引用访问静态变量。 PHP 有,但这并不意味着它与 优秀的 OO 设计 有关
  • @zerkms "从单例中检索的静态实例" 听起来很脏:))。我现在觉得我处于 OOP 的阴暗面。
  • 问题:$db 变量是在构造函数中赋值的,在调用静态方法时没有调用。那么我该如何处理呢? “访问未声明的静态属性”
【解决方案2】:

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

【讨论】:

  • 由于大多数时候您是从实例化类调用静态方法,因此将 DB 对象传递给静态方法是不必处理尝试声明DB单例类作为静态。在我的情况下,这个答案非常有效,并没有造成混乱。
猜你喜欢
  • 1970-01-01
  • 2011-03-26
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多