无法获取MySQL

时间:2013-03-11 00:59:21

标签: php mysql oop

我正在尝试重新编写我制作的主页。这次我想使用OOP样式,但我总是得到以下错误:

  

Statistic :: 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();

1 个答案:

答案 0 :(得分:1)

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

  • 您的MySQL类扩展MySQLi(即,任何MySQL对象也是MySQLi对象)并“委托”到MySQLi实例在其私有变量$db
  • 你的Statistic类在其构造函数中采用MySQL的实例(“依赖注入”),但随后忽略它并向MySQL类询问“单例”实例。 / LI>

您需要更仔细地阅读每种模式的用途,并在每种情况下决定一个或另一个(继承委派,依赖注入单身人士)。

目前,您的代码将执行以下操作:

  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步忽略了它。)