2013-03-11 31 views
0

嘿那里即时尝试重新编码我做的一个主页。这一次我想使用OOP风格。但是,我总是得到以下错误:无法取得MySQL

统计:: checkExistingCounter()[statistic.checkexistingcounter]:无法获取的MySQL

我在做什么错?我知道准备陈述是毫无意义的,但即使只是一个查询而不是准备陈述也根本不是什么东西。同样的错误:无法获取的MySQL

我的数据库类:

class MySQL extends MySQLi { 

    private static $_instance = null; 
    private $host, $username, $password, $db; 

    public static function getInstance() { 
     if (!(self::$_instance instanceof self)) { 
      self::$_instance = new self(); 
     } 
     return self::$_instance; 
    } 

    public function __construct(){ 
     $this->host = '...'; 
     $this->username = '...'; 
     $this->password = '...'; 
     $this->database = '...'; 
     $this->connect(); 
    } 

    public function __destruct() { 
     $this->db->close(); 
    } 

    private function __clone(){} 

    public function connect() { 
     $this->db = @new MySQLi($this->host, $this->username, $this->password, $this->database); 

     /* change character set to utf8 */ 
     $this->db->set_charset("utf8"); 

     if (mysqli_connect_errno()) { 
      printf("Connect failed: %s\n", mysqli_connect_error()); 
      exit(); 
     } 

     return $this->db; 
    } 
} 

我的统计类:

class Statistic { 
    private $remote, $user_agent, $referer; 
    private $db; 

    /** 
    * Create Instance of MySQL 
    **/ 
    function __construct($db) { 
     $this->db = MySQL::getInstance(); 
    } 

    /** 
    * Check for counter today 
    * 
    * @param: string SQL 
    * @return: boolean (true = Counter exists, false = Counter doesnt exist) 
    **/ 
    function checkExistingCounter($sql) { 
     $stmt = $this->db->prepare($sql); 

     $this->db->error; 

     if (!$stmt) { 
      echo 'Datenbankfehler'; 
      exit; 
     } 

     $stmt->execute(); 
     $stmt->store_result(); 

     if ($stmt->num_rows) { 
      $stmt->close(); 
      return true; 
     } else { 
      $stmt->close(); 
      return false; 
     } 
    } 

    function counter() { 
     $sql = "SELECT ID FROM Counter WHERE Datum = CURDATE()"; 
     $checkCounter = $this->checkExistingCounter($sql); 
    } 

这是我的index.php的一部分:

$db = new MySQL(); 
$statistic = new Statistic($db); 
$statistic->counter(); 
+0

'MySQL :: getInstance'是做什么的? – 2013-03-11 02:05:26

+0

@ExplosionPills它看起来非常像我的单身模式。 – IMSoP 2013-03-11 02:18:52

回答

1

你似乎陷入了困境,实施了两套竞争编码模式:

  • MySQL类都扩展MySQLi(即任何MySQL对象也是一个MySQLi对象),并在其私有变量“代表”到MySQLi实例$db
  • Statistic类需要的MySQL一个实例在其构造函数(“依赖注入”),但然后忽略它,并要求MySQL类为“单例”实例。

你需要更仔细地什么这些模式是读了起来,并决定一个或另一个在每种情况下(继承代表团,依赖注入单身)。

目前,您的代码将做到以下几点:

  1. 创建一个新的MySQL对象(这也是一个MySQLi对象,但尚未初始化任何特定数据库的连接,因为你已经不叫在MySQL构造parent::__construct()
  2. ,设置$this->host
  3. connect()方法,创建一个新MySQLi对象,并向它的主机等
  4. 保存这个对象为$this->db,它永远只能在析构函数($this->db->close()
  5. 回报从connect()MySQLi对象,但没有在__construct()正在寻找该返回值
  6. 回在外部编码,在MySQL对象引用传递给Statistic
  7. 构造则忽略此的构造函数,并调用辛格尔顿方法MySQL::getInstance()代替
  8. getInstance()方法(因为这是它第一次被调用)将创建第二个MySQL对象,重复步骤1至5
  9. 此第二MySQL对象将在Statistics对象
  10. checkExistingCounter方法试图使用$this->db作为MySQLi连接上保存为$this->db,但MySQL对象从未连接到任何数据库,所以你得到一个错误。 (有一个连接的连接,如果它不是私人的,你可以访问它作为$this->db->db。还有一个踢,以及在第2步创建,但你不能再访问,因为你忽略它在第7步。)
+0

感谢您指出。嗯,我想我需要阅读更多关于单身模式。 – JPM 2013-03-11 02:41:08