1

グローバル変数 global $db3; を作成したとします。($db3 は実際には別のクラスの指示されたオブジェクトです)。このグローバル変数をすべてのメソッドに 1 つずつ渡すのではなく、この変数をクラスのすべてのメソッドにデフォルトで渡したいと考えています。

私の最初のデータベースクラスは

class dtb{
public $connection;

public function __construct(){

    $this->connection=mysqli_connect('localhost','root','','new5');

     }

     }
 $db3=new dtb();

そして、2番目のクラスは次のとおりです

  session_start();
  $a = new session($db3);

       class user{
         public $db;

          public function __construct($db)
    {
        $this->db = $db;

    }

function login(){
 //global $db3;


 //$db3->show_new();
   $results=mysqli_query($this->db->connection,"select * from user");  //(I want to use $db3 of another class here as resource link)


      }


   }
4

3 に答える 3

5

コード例には、質問で求めていることに関連するいくつかの問題があるため、それらを強調したいと思います。

最も目に見える問題は、データベース接続オブジェクトを渡さないことです。代わりに、dtb後でラップを解除するだけのタイプにラップします。たとえば、あなたのuser:

function login() {
   ...

   $results = mysqli_query($this->db->connection,"select * from user");
                                  ^--^--- unwrapping
   ...

代わりに、userタイプには接続が必要です。dtbラッピングについて知る必要はありません。

function login() {
   ...

   $results = mysqli_query($this->connection, "select * from user");
                                      ^--- one thing, not one thing and another
   ...

mysqli次に、拡張機能の OO インターフェイスを使用していません。あなたのコード例は、これがコードを不必要に複雑にすることをよく示しています。mysqli のやり方でやってみましょう:

function login() {
   ...

   $results = $this->connection->query("select * from user");

   ...

ご覧のとおり、特定の関数を使用せずに、オブジェクトのメソッドをmysqli_*使用するだけで接続を利用できます。query

そのため、これは 1 行のコードでかなりローカルになりました。非オブジェクト指向のバックグラウンド グローバル変数でこれまで使用してきたもの$connectionのために、オブジェクトは に入る必要があります。userただし、オブジェクト指向プログラミングでは、クラスのコードで使用されるグローバル変数があってはなりません。これは、手続き型コードのグローバル変数が$thisクラスの変数であるためです。$thisメソッド パラメータが指定されていない場合は、クラス内のメソッドが必要とするすべてのものを保持する必要があります。

したがって、さまざまなクラスはデータベース接続に基づいています。各クラスに入れたいと思います。クラスは、そのコンストラクター メソッドで初期化されます。そこで、クラスを初期化するために必要なパラメーターとしてすべてを渡します。userクラスの例を見てみましょう:

class User
{
    private $connection;

    public function __construct(Mysqli $connection) {
        $this->connection = $connection;
    }

    public function login() {
        $resultSet = $this->connection->query("SELECT * FROM user;");
    }
}

ご覧のとおり、は接続を取得するUserコンストラクター メソッドで初期化されます。そのプライベート変数に割り当てられているため、その接続を使用できます。__constructMysqli$this->connection

クラスがインスタンス化されると、接続が同じままになるので安心できます。これは、別のデータベースへの接続を並行して開く必要がある場合にも役立ちます。作成する必要がある Mysqli 接続の数に関係なく、コードは引き続き機能します。

それでは、使用方法について説明します。

$connection = new Mysqli('localhost','root','','new5');

$user = new User($connection);

$user->login();

以上です。確かに、Mysqli 接続オブジェクトを作成する場所とユーザーを作成する場所の間に何らかのコードがあるかもしれませんが、必要なのは接続を渡すことだけです。

これはここで終わりではありませんが、私はすでにここでブログ投稿に近づいています. おそらくやりたいことは、各クラスの接続の詳細の負担を取り除き、代わりに、反復的なデータベース対話コードを処理する基本クラスから拡張して、上位レベルのクラスでより集中できるようにすることです。データベースの詳細については作業しません。それにはさまざまな方法があります。基本クラスからの拡張は、そのうちの 1 つにすぎません。非常に単純化された例:

class Database
{
    private $connection;

    public function __construct(Mysqli $connection) {
        $this->connection = $connection;
    }

    protected function query($sql) {
        return $this->connection->query($sql);
    }
}

class User extends Database
{
    $resultSet = $this->query("SELECT * FROM user;");
}

たとえば、プロパティの名前だけが異なる共通のクラスのセットがある場合、共通の基本クラスにはそれを実現するためのコードを含めることができ、それから拡張するクラスはそのためのパラメーターを指定するだけで済みます。

しかし、書かれているように、クラスをデータベース接続にマップするにはさまざまな方法があります。それらをまったくマッピングしたくない場合があります。あなたに一番合ったことをして、少し遊んでください。常にコンストラクターで初期化し、グローバル (およびグローバルである静的クラス変数) を使用しないようにすると、柔軟性が保たれ、実際にはもっとうまく遊ぶことができます。

そして覚えておいてください:誰もが水で料理をしています。その背後に魔法はありません.

于 2012-11-03T16:08:41.097 に答える