0

作成したホームページを再コーディングしようとしています。今回は OOP スタイルを使用したいのですが、常に次のエラーが発生します。

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

1 に答える 1

1

あなたはここで混乱しているようで、2 つの競合するコーディング パターンのセットを実装しています。

  • あなたのMySQLクラスは拡張MySQLiされ(つまり、任意MySQLのオブジェクトもオブジェクトです) 、そのプライベート変数MySQLiのインスタンスに「委譲」されますMySQLi$db
  • あなたのStatisticクラスはコンストラクターで のインスタンスを取りますがMySQL(「依存性注入」)、それを無視してMySQLクラスに「シングルトン」インスタンスを要求します。

これらの各パターンの目的をより注意深く読み、それぞれの場合 (継承または委譲、依存性注入またはシングルトン) でどちらかを決定する必要があります。

現在、コードは次のことを行います。

  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. MySQL::getInstance()コンストラクターはこれを無視し、代わりに Singleton メソッドを呼び出します
  8. このgetInstance()メソッドは (初めて呼び出されたため) 2 番目のMySQLオブジェクトを作成し、ステップ 1 から 5 を繰り返します。
  9. この 2 番目のMySQLオブジェクトはオブジェクトとして保存さ$this->dbStatisticsます
  10. checkExistingCounterメソッドは接続として使用しようとしますが$this->dbMySQLiオブジェクトMySQLはデータベースに接続されていないため、エラーが発生します。(接続された接続があり、それがプライベートでない場合は、としてアクセスできます$this->db->db。ステップ 2 で作成された別の接続もありますが、無視したため、これ以上アクセスできません。手順 7)
于 2013-03-11T02:08:26.997 に答える