Singleton类出了点问题,不知道是什么

时间:2011-02-06 15:48:50

标签: php oop singleton pdo

我之前从未做过任何Singleton类,现在我认为对于这个数据库连接来说,创建一个是个好主意,但我不知道为什么它不能正常工作。如果有人能帮我解决这个问题,我真的很感激,因为我想了解OOP的工作原理......

无论如何,我修改它只是将我的PHP更新到最新版本,现在$DBH = new static();工作正常,谢谢大家。

我尝试使用$DBH = new static();而不是$DBH = new self();但是我有这个错误:

  

解析错误:语法错误,意外   T_STATIC,期待T_STRING或   mSingleton.php上的T_VARIABLE或'$'   第14行

错误:

  

致命错误:无法实例化   抽象类Singleton in   第14行的mSingleton.php

文件: (mSingleton.php)     

abstract class Singleton
{

    protected $DBH;

    public static function getInstance()
    {
        if ($DBH == null)
        {
            $DBH = new self();
        }

        return $DBH;
    }

}

(mDBAccess.php)

<?php
//mDBAccess.php
//Removed values ofc
$db_host = "";
$db_name = "";
$db_user = "";
$db_pass = "";

include "mSingleton.php";

class DBAccess extends Singleton
{
    protected $DBH;

    function __construct()
    {
        try
        {
        $this->DBH = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
        $this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
        }
        catch (PDOException $e)
        {
            echo $e->getMessage();
        }
    }

    public static function getDBH()
    {
        return self::getInstance()->DBH;
    }
}

(mLog.php)

<?php
//mLog.php
include "mDBAccess.php";

class Log
{

    public static function Add($action)
    {
        try
        {
            $DBH = DBAccess::getDBH();

            //Getting user IP
            $ip = $_SERVER['REMOTE_ADDR'];

            //Getting time
            $time = date('Y-m-d');

            //Preparing our SQL Query
            $values = array($ip, $action, $time);
            $STH = $DBH->prepare("INSERT INTO log (ip, action, time)
                                  VALUES (?, ?, ?)");

            //Excecuting SQL Query
            $STH->execute($values);
        }
        catch (PDOException $e)
        {
            echo $e->getMessage();
        }
    }

}
//testing..
Log::Add("ddd");

5 个答案:

答案 0 :(得分:2)

你需要写

$DBH = new static();

请参阅:Late Static Binding

答案 1 :(得分:2)

我对PHP 5的解决方法&lt; 5.3用于抽象的Singleton类。

取自:http://code.google.com/p/phpraise/source/browse/trunk/phpraise/core/RaiseSingleton.php

/**
 * RaiseSingleton abstract class
 * Defines a Singleton class
 *
 * @author Sam Yong
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
 * @abstract
 * @package Raise.Core
 */
abstract class RaiseSingleton extends RaiseObject {

    /**
     * Prevent creation of a new instance
     * Constructor not set to final to allow overrides in subclass
     */
    protected function __construct() {}

    /**
     * Prevent cloning of the Singleton instance
     * @final
     */
    final private function __clone() {}

    /**
     * Return the Singleton instance
     * @return object
     * @staticvar static $__instance
     */
    public static function getInstance() {
        static $__instance;
        $class = get_called_class();
        return $__instance ? $__instance : $__instance = new $class();
    }
}

基本上,在取消所有phpRaise必需品后:

abstract class Singleton {

    protected function __construct() {}

    final private function __clone() {}

    public static function getInstance() {
        static $__instance;
        $class = get_called_class();
        return $__instance ? $__instance : $__instance = new $class();
    }
}

答案 2 :(得分:0)

self指向抽象类,并且您无法实例化抽象类,如果要保留该组织,则必须使用new static()

答案 3 :(得分:0)

$DBH = new self();$DBH = new Singleton();相同,后者已被标记为抽象以防止实例化。

您应该使用Late Static Binding来启动子类的新obhect,尝试使用new static()

答案 4 :(得分:0)

我会提前说我不熟悉PHP,但有一些事情对我很有帮助。

  • $ DBH在DBAccess中重新定义,首先在Singleton中声明它。
  • 在Singleton中的$ DBH未声明为静态,那么$ DBH = new static()如何工作?除非使用static绑定将$ DBH转换为静态存储区域。
  • 如果您将Singleton中的$ DBH转换为静态变量,那么如果其他任何内容都来自Singleton,您将会遇到问题。

除非有人更聪明并且可以创建可用于其子类的Singleton类,否则最好将逻辑直接放入DBAccess类。如果有人能解决语义和语法错误,我会很感激。

class DBAccess
{
    private static $_instance;

    protected $DBH;

    function __construct()
    {
        try
        {
            $this->DBH = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
            $this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
        }
        catch (PDOException $e)
        {
            echo $e->getMessage();
        }
    }

    public static function getDBH()
    {
        if ($_instance == null)
            $_instance = new DBAccess();
        return $_instance->DBH;
    }
}