【问题标题】:Singleton class for database mysqli phpversion 5.2.17数据库 mysqli phpversion 5.2.17 的单例类
【发布时间】:2014-04-14 22:20:30
【问题描述】:

我在为多个类使用的 mysqli 对象构建单例类时遇到了一些问题。我最初收到错误Access to undeclared static property: database::$DBH,我不明白,因为该属性不是静态的。我推测这可能是因为phpversion() 返回了 5.2.17 并且我发现单例模式只能使用 >5.3 版本来完成? (可能完全错误)。我调查了一下,发现我的服务器提供商允许我选择我可以使用的 PHP 版本。我目前选择了 5.3.3,但同样的错误。要么我必须等待服务器“刷新”它的设置。或者我在 5.3.3 版本中确实存在合法错误

class database{
    private$DBH;
    private static$singleton;
    protected function __construct(){
        $this->$DBH=new mysqli(HOST,USER,PASSWORD,DATABASE);
        //also tried self::$DBH;
        //if(mysqli_connect_errno())print_r(mysqli_connect_error());
    }
    public static function instance(){
        if(!(self::$singleton instanceof self))self::$singleton=new self();
        return self::$singleton;
    }
    public static function get(){
        return self::instance()->$DBH;
    }
    private function __wake(){}
    private function __clone(){}
}
class test{
    public function __construct(){
        $get=database::get()->prepare('SELECT column FROM table');
        $get->execute();
        $get->bind_result($col);
        while($get->fetch()){
            print($col."\n");
        }
        //$get->close(); not required.
    }
}
$t=new test();

是否有任何替代方案可以让我尝试实现? (与多个类一起使用的单个 mysqli 对象,也是标准对象的“安全”方法。)

我应该用 mysqli 扩展我的数据库类吗?

我应该只使用 PDO 吗?

或者还是更好!找一个更好的服务器提供商,他们的服务是最新的。

【问题讨论】:

    标签: php class oop mysqli singleton


    【解决方案1】:

    不要让它过于复杂,只需扩展MySQLi 类,添加一些方法即可。 MySQLi 本身已经是一个连接器,为什么还要在一个连接器中存储另一个连接器?

    class Database extends MySQLi {
         private static $instance = null ;
    
         private function __construct($host, $user, $password, $database){ 
             parent::__construct($host, $user, $password, $database);
         }
    
         public static function getInstance(){
             if (self::$instance == null){
                 self::$instance = new self(HOST, USER, PASSWORD, DATABASE);
             }
             return self::$instance ;
         }
    }
    
    $db = Database::getInstance();
    $result = $db->query("SELECT 1 FROM table");
    

    一些提示:

    • Non-static 属性通过$object->property 访问

    • Static 属性通过以下方式访问:self::$propertyDatabase::$propertystatic::$property

    • 使用PDO 非常好,因为您可以绑定值,从而保护您的数据库免受注入。作为一个选项 - 扩展 PDO 类。

    【讨论】:

    • 谢谢!抱歉,回复很长,这正是我想要实现的。我注意到您的脚本中没有包含“功能”。为什么会这样?
    • 不幸的是,你不能从扩展 mysqli(或 PDO)的类中创建单例类,因为真正的单例需要将构造函数方法设为私有(为了不能实例化单例),另一方面 mysqli 构造函数是公共的,并且您不能用私有方法覆盖公共方法。如果您尝试在继承的(单例)类中使用私有构造函数覆盖 mysqli 的公共构造函数,PHP 将返回致命错误。
    【解决方案2】:

    您需要从$DBH 中的$this->$DBH=new mysqlireturn self::instance()->$DBH; 中删除$,因为您已经使用$this->DBH 引用了它的当前对象

    class database{
        private $DBH;
        private static $singleton;
        protected function __construct(){
            $this->DBH=new mysqli(HOST,USER,PASSWORD,DATABASE);
            //also tried self::$DBH;
            //if(mysqli_connect_errno())print_r(mysqli_connect_error());
        }
        public static function instance(){
            if(!(self::$singleton instanceof self)) self::$singleton=new self();
            return self::$singleton;
        }
        public static function get(){
            return self::instance()->DBH;
        }
        private function __wake(){}
        private function __clone(){}
    }
    class test{
        public function __construct(){
            $get=database::get()->prepare('SELECT column FROM table');
            $get->execute();
            $get->bind_result($col);
            while($get->fetch()){
                print($col."\n");
            }
            //$get->close(); not required.
        }
    }
    $t=new test();
    

    【讨论】:

      猜你喜欢
      • 2023-01-30
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多