4

userdbデータベースへの接続を返す関数を宣言するクラスがあります。

return $con = new PDO("mysql:host=$host;dbname=$db", $user, $pass);

アクセスする必要がある他のクラス間であっても、さまざまな関数があります$con(たとえば、クエリを渡したり、データをフェッチしたりするため)、この変数にアクセスできません。

データベース クラスを定義して使用するためのより良い方法はありますか? クラスにアクセスする必要がある他のクラスがあることを思い出してくださいuserdb

4

7 に答える 7

3

これにはシングルトンパターンを使用することをお勧めします。

userdbクラスで、静的プロパティを宣言します$scon

private static $scon;

上記の関数の名前がcreateConnection()であると仮定すると、次の静的メソッドを作成する必要があります。

public static function connect() {
    if (empty(self::$scon)) {
         $instance = new userdb();
         self::$scon = $indtance->createConnection(); 
    }
    return self::$scon; 
}

これにより、次のコマンドでuserdb接続にアクセスできるようになります。

userdb::connect();

また、これはシングルトンであるため、1回だけ接続し、スクリプトの最後までその接続を使用します。

注(依存性注入について): @ KevinM1が依存性注入について言及しているので、それも可能であり、はるかに優れたソリューションであることを付け加えなければなりません。データベース接続を使用してすべてのクラスのsetConnection()メソッド(または抽象祖先)を作成する必要があります。これらのクラスのインスタンス化中に、ファクトリを使用して必要な接続をオブジェクトに追加できます。これは、モデル構造のさまざまなクラスローダー内にラップする必要があります。

ほら、ケーキの平和ですが、小さくて速い開発のために、私はシングルトンに固執します;)

于 2012-10-19T11:58:53.070 に答える
1

クラスにある場合は、インスタンスをプロパティに保存します。

class userDB
{

   public $dbCon = false;//because you want to access the instance 
   //from outside the class, I have made the property public

    function connect()
   {

      $con = new PDO("mysql:host=$host;dbname=$db", $user, $pass);

      $this->dbCon = $con;

   }


}

クラス外からアクセスするには:

$useDBInstance->dbCon;

于 2012-10-19T11:52:07.920 に答える
0

$ conは、新しいPDOオブジェクトをインスタンス化するため、すでにオブジェクトになっています。PDOオブジェクトに機能を追加しようとしているのでない限り、それをラップしても意味がありません。

とはいえ、userdb / PDOオブジェクト(ラッパーを使用するかどうかによって異なります)を他のオブジェクトと共有する最良の方法は、依存性注入を使用することです。これは、dbを必要なオブジェクトに渡すための空想的な用語です。PHPではオブジェクトはデフォルトで参照によって渡されるため、最初にdbオブジェクトを作成すると、コンストラクター/メソッド引数としてオブジェクトを受け取るすべてのオブジェクトが同じ単一のインスタンスを使用します。

編集:依存性注入の実装へのリンク

EDIT2:小さなプロジェクトでのDIの明確化-

通常のDIパターンには、通常、DIコンテナと呼ばれる特別なオブジェクトが必要です。これは、依存関係を必要とするオブジェクトに自動的に依存関係を挿入する特殊用途のオブジェクトです。小さなプロジェクトの場合、それはやり過ぎです。DIの単純で複雑度の低いバージョンは、次のとおりです。

class SomeClass {
    protected $db;

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

class SomeClass2 {
    public function SomeMethod($db) {
        // do something with the db
    }
}

$db = new PDO(/* connection string */);

$obj = new SomeClass($db, /* other constructor args */);

// or

$obj2 = new SomeClass2(/* constructor args */);
$obj2->someMethod($db, /* method args */);

魔法は、オブジェクトがPHPでデフォルトで参照によって渡されるため、$objと$obj2が同じdb接続を使用することです。

全体的な考え方は、静的メソッドを使用してスコープやカプセル化を壊さないようにすることと、クラスとそのメソッドが機能するために必要なものについて前もって確認することです。

シングルトンは正反対です。これらはスコープをバイパスする静的メソッドを介してアクセスされ、呼び出されて渡されないため、メソッドシグネチャに表示されることはありません。したがって、コードに精通していない人は、その隠された要件に気付くことはありません。 シングルトンパターンの成文化を支援したエーリヒガンマでさえ、それについて後悔しています:

私はシングルトンを落とすことに賛成です。その使用は、ほとんどの場合、デザインの匂いです。

共有メモリの概念がなく、スクリプトがリクエストごとに1回実行されるPHPでは、シングルトンを使用する唯一の理由は、単一のリソースに簡単にアクセスできるようにすることです。オブジェクトは参照によって渡されるため、1つのインスタンスを複数のオブジェクトと自然に共有できます。そこから、それは優れた設計と委任についてです。

于 2012-10-19T11:56:55.210 に答える
0
return $this->con 

クラスからこの方法で戻り、この方法で呼び出します..

$this->classObject->con->prepare();
于 2012-10-19T11:52:00.637 に答える
0

グローバル PHP 変数に代わる方法については、私のビデオ チュートリアルとコードをご覧ください。

あなたはそこで間違っています。関数で接続を作成してそこに保存する場合は、静的変数を使用する必要があります。そうしないと、すべての関数呼び出しで接続し続けることになります。私のチュートリアルでは、通常の関数内の静的変数のまさにこの概念について説明しています。

よくわからない場合はお知らせください。質問にお答えします。

これに付随するコードを次に示します。

/**
* Arguments are none or [$db, [$user, [$pass[, $host]]]].
*
* @return PDO
*/
function PdoDb(){
    static $con = null; // I'm explicit :)
    // Every time you pass Arguments you reconnect
    if(func_num_args()){
        $args = array_pad(func_get_args(), 4, null);
        list($db, $user, $pass, $host) = $args;
        if(empty($user)) $user = 'root';
        if(empty($host)) $host = 'localhost';
        $con = new PDO("mysql:host={$host};dbname={$db}", $user, $pass);
    }
    if(empty($con)){
        trigger_error('Provide arguments to connect first.', E_USER_ERROR);
        return null;
    }
    return $con;
}

// First run (provide arguments to connect)
PdoDb($db, $user, $pass, $host);
PdoDb($db); // Works if you connect root@localhost with no password

// From here on (it returns PDO)
PdoDb()->DoStuffOfPdo();

接続したらそのままです。ただし、引数を指定することで、自由に再接続できます。

于 2012-10-19T12:18:32.803 に答える
-2

singltonクラスの実装を使用する

class connectdb
{
    protected static $_instance = NULL;


    private function __construct()
    {
    }

    public function getinstance()
    {
     if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
    public function connect()
    {
     $this->connection =new PDO("mysql:host=$host;dbname=$db", $user, $pass);


    }

}
于 2012-10-19T11:57:59.693 に答える
-4

クラス関数または独立関数内で変数を使用するには、グローバル キーワードを配置する必要があります

$conn=mysql_connect(); 
   function test(){
      global $conn;
   }

$connテスト関数の範囲内で使用できるようになり、スクリプトの先頭で定義するとどこでも使用できるようになります。クラスについても同じことを行う必要があり、クラスのオブジェクトを作成し、関数内でグローバルとして宣言します

于 2012-10-19T11:55:43.147 に答える