2013-03-11 3 views
0

Эй, я пытаюсь переделать домашнюю страницу, которую я сделал. На этот раз я хочу использовать стиль ООП. Но я всегда получаю следующее сообщение об ошибке:Не удалось получить MySQL

Статистика :: checkExistingCounter() [statistic.checkexistingcounter]: не удалось извлечь MySQL

Что я делаю неправильно? Я знаю, что инструкция prepare бессмысленна, но даже запрос, а не запрос подготовки, вообще не разыгрывается. То же ошибка: не удалось получить 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'? –

+0

@ ExplosionPills Это очень похоже на Pattern Singleton для меня. – IMSoP

ответ

1

Вы, кажется, находитесь в путанице здесь, реализуя два набора конкурирующих шаблонов кодирования:

  • вашего MySQL класс и расширяет MySQLi (то есть, любой MySQL объект также MySQLi объекта) и «делегаты» друг MySQLi например в своем приватном переменной $db
  • вашего Statistic класса принимает экземпляр MySQL в его конструктор («инъекция зависимостей»), но затем игнорирует его и задает класс MySQL для экземпляра «singleton».

Вы должны прочитать более внимательно на то, что каждая из этих моделей для, и решить, на одной или другой в каждом случае (наследование или делегации, инъекции зависимостей или одиночек).

В настоящее время, ваш код будет делать следующее:

  1. создать новый MySQL объект (который также является MySQLi объекта, но не инициализируется каким-либо конкретное соединение с базой данных, потому что вы не вызвали parent::__construct())
  2. в MySQL конструктор, набор $this->host и т.д.
  3. в методе connect(), создать новый объект MySQLi, передавая его хозяина и т.д.
  4. сохранить этот объект как $this->db, который только когда-либо ссылка в деструкторе ($this->db->close())
  5. возвращает MySQLi объект из connect(), но ничего в __construct() смотрит в том возвращаемом значении
  6. назад во внешнем коде MySQL объекта передается в конструктор класса Statistic
  7. конструктор затем игнорирует это и вызывает метод Singleton MySQL::getInstance() вместо
  8. getInstance() метод (так как это первый раз он был назван) создаст второй MySQL объекта, повторяя шаги 1 до 5
  9. этого второго MySQL объект будет сохранен как $this->db на Statistics объекте
  10. метод checkExistingCounter пытается использовать $this->db как MySQLi связи, но объект MySQL не был подключен к любой базе данных, поэтому вы получите сообщение об ошибке. (Существует подключенное соединение, и если оно не было закрытым, вы можете получить доступ к нему как $this->db->db. Также есть еще один способ, который был создан на шаге 2, но вы не можете получить доступ к нему больше, потому что вы проигнорировали это на этапе 7.)
+0

Благодарим за указание. Ну, я думаю, мне нужно больше узнать об одноэлементных моделях. – JPM

Смежные вопросы