PHP:正确使用单例模式?

时间:2011-02-10 18:11:12

标签: php oop design-patterns singleton

我正在尝试学习PHP OOP,并对如何在我的项目中使用全局数据库类进行了一些研究。从我所看到的,最合适的模式是一个单例,它可以确保始终只存在一个数据库连接。然而,由于这是我第一次使用Singleton模式,我不确定我是否做得对。

这是一个合适的单身人士吗?此代码是否仅确保一个数据库连接?有什么办法可以测试吗? (学会钓鱼的人,他将在余生中获得食物......)

我使用redbean作为我的ORM,这是我如何明确地设置它:

require_once PLUGINPATH.'rb.php';
$redbean= R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');

我已根据this source创建了以下脚本,作为我自己的单例数据库类;

class database {
    private $connection = null;

    private function __construct(){
        require_once PLUGINPATH.'rb.php';
        $this->connection = R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');
    }

    public static function get() {
        static $db = null;

        if ( $db === null )
        $db = new database();

        return $db;
    }

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

谢谢!

2 个答案:

答案 0 :(得分:6)

实例变量必须是类的静态成员。我没有测试过这段代码,但它应该可行。连接也应该是静态的。使用此代码,您将拥有一个数据库类实例和一个连接实例。可以在没有静态连接的情况下执行此操作,但将其设置为静态将确保只有一个连接实例。我还将类的文字名称更改为php magic constants。这使您的代码更易于维护。如果您在路上更改班级名称,则无需在代码中查找旧班级名称的所有文字实例。现在看起来似乎有些过分,但相信我,当你在越来越复杂的项目上工作时,你会欣赏它的价值。

class database {
    private static $connection = null;
    private static $db;

    private function __construct(){
        require_once PLUGINPATH.'rb.php';
        self::$connection = R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');
    }

    public static function get() {
        if ( !(self::$db instanceof __CLASS__) ) {
            $klass = __CLASS__; // have to set this to a var, cant use the constant with "new"
            self::$db = new $klass();
        }

        return self::$db;
        }

    public function connection() {
        return self::$connection;
    }
}

答案 1 :(得分:2)

你的单身几乎是正确的。

私人成员(没有双关语)$connection也需要是静态的。您也可以使用以下内容:

class database {
    private static $instance = NULL;
    protected $conn;

    private function __construct() {
        $this->conn = mysql_connect( ... );
    }

    public static function init() {
        if (NULL !== self::$instance) 
            throw new SingletonException();
        self::$instance = new database();
    }

    public static function get_handle() {
        if (NULL === self::$instance)
            ; // error handling here
        return self::$instance->conn;
    }
}