2017-03-29 16 views
0

DBに接続するためのクラスがDatabaseです。PHP OOP-別のクラスの構築メソッドにDBクラスを注入する

<?php 

require_once('config.php'); 

class Database { 

    function __construct(){ 
    $this->connect(); 
    } 

    public function connect(){ 
    $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE); 
    } 

} 

?> 

そして、私はDB接続を使用する必要がメインクラス:

include 'includes/database.php'; 

class Main{ 

    var $mysqli; 

    public function __construct(){ 
     $this->mysqli = new Database(); 
    } 

しかし、これは私がメインのクラスに残っているクエリのエラーを取得するので、私が意図し、動作していません後でそれらをDBクラスに移動します。しかし、今、私はエラーを取得しています:

Fatal error: Uncaught Error: Call to undefined method Database::query() in /home/vagrant/Projects/MyProject/index.php on line 262

問合せは、メインクラスで行われています。

$result = $this->mysqli->query("SELECT shops.*, shops.id AS shop,SUM(price)... 
+0

$ this-> mysqli-> query();というクエリ関数にアクセスします。 – Akintunde007

+0

ここでは 'query'の使い方は表示されません。 –

+0

データベースクラスの' query() 'の呼び出しは' $ this-> connection-> query() 'でなければなりません。 'query()'メソッドを使用して 'Database'クラスに直接ラップします。 'query()'を呼び出そうとしているところにコードを投稿してください。 –

答えて

1

あなたはDatabaseクラスのquery()メソッドを呼び出そうとしています。そのクラスは$connectionプロパティにmysqliオブジェクトを含んでいますが、mysqliオブジェクトのquery()メソッドは公開されていません。

あなたの現在のコードでは、mysqliに直接query()を呼び出すためにオブジェクト構造にさらにドリルすることができますが、これは面倒です。

// Call the query() method directly on the connection 
$result = $this->mysqli->connection->query("SELECT shops.*, shops.id AS shop,SUM(price)... 

それはあなたのクラスは、彼らはおそらく必要以上Databaseクラスの内部の仕組みについての詳細を知ることが必要ですので、私はこのアプローチを好みません。それはあまりにも強く結びついている。

代わりにmysqliオブジェクトの必要な機能をラップするDatabaseクラスにquery()メソッドを作成することができます。

class Database { 

    function __construct(){ 
    $this->connect(); 
    } 

    public function connect(){ 
    $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE); 
    } 

    // Expose a query() method that calles the inner mysqli's query 
    public function query($sql) { 
    return $this->connection->query($sql); 
    } 
} 

これは、1回のメソッド呼び出しですべての結果行を照会し、フェッチなど、より多くの機能、中にパックすることができます:あなたはそれをこの方法を行うと、あなたが呼び出すことができるはずです

class Database { 
    //.... 

    // A more featured query() that returns the 
    // rows as an array 
    public function query($sql) { 
    $result = $this->connection->query($sql); 
    while ($row = $result->fetch_assoc()) { 
     $rows[] = $row; 
    } 
    // Return an array of all the rows fetched from the query 
    return $rows; 
    } 
} 

$this->mysqli->query("...")最初に試行したように、シンプルなバージョンで結果リソースを取得してください。その後、コードを自分で取得するか、より機能的なバージョンの連想検索結果の配列を取得する必要があります。

これらの種類のデータベースラッパークラスを作成すると、かなり迅速に扱いにくくなる可能性があります。アプリケーション内の他のクラスに公開するオブジェクトのうち、どのオブジェクトがどのような側面になっているかを慎重に検討してください。 Databaseクラスのmysqliメソッドをラップする方法はお勧めできません。その時点でDatabaseクラスのユーティリティが大幅に削減され、mysqliオブジェクトを直接渡すこともできます。 mysqliに機能を積極的に追加していない場合、それをラップする別のクラスを作成するのはあまり意味がありません。

注記:var $mysqli; ...これは古い廃止予定のクラスプロパティ構文です。 varのキーワードはPHP4の痕跡であり、その使用は現在は推奨されていません。実際、最近のPHPのバージョンからは削除されています。代わりに、あなたはPHP5 +構文を経由して、それを宣言する必要があります:あなたの質問のタイトルで

// Declare as a public property 
public $mysqli; 

// Or better, as a private (or protected) property so it cannot 
// be accessed outside the Main class' own methods 
private $mysqli; 

は、あなたが注入を述べました。あなたのクラスはそれを今はやっていませんが、Databaseを事前にインスタンス化し、それを必要とするクラスコンストラクタに挿入することをお勧めします。重要なのは、これはため別ののデータベース接続を開くからあなたが構築あなたがMainのインスタンスごとオブジェクトと他のクラスのを防止することができます

$db = new Database(); 
// Pass the $db to the other classes 
$main = new Main($db); 

class Main{ 

    public $mysqli; 

    // Pass a database as a constructor param 
    public function __construct($database){ 
     $this->mysqli = $database; 
    } 

次にとしてそれをインスタンス化同じ方法。そうすることで、サーバーの利用可能なMySQL接続をすぐに使い切ることができます。

+0

@Leffこれは意味がありますか? –

+0

非常にしっかりした答え! 'public'の代わりに' private $ mysqli'を使うとオブジェクトの外側からプロパティにアクセスすることができず、疎結合を強制することができません。 +1でも –

+0

@ᵈˑᵈˑ私は同意しますが、あまりにも多くの概念を導入したり、OPの独自の方法論をあまりにも多く変更したりしたくありませんでした。私はそれについて別のメモを追加します。 –

関連する問題