web-dev-qa-db-ja.com

シングルトン、静的、またはその他のクラス間で受け渡しされるDBオブジェクト?

だから私は職場でレポーティングシステムを設計しています。それはOOPで書かれた私の最初のプロジェクトであり、DBクラスの設計の選択に行き詰まっています。
明らかに、セッションごと/ユーザーごとにDBクラスのインスタンスを1つだけ作成し、それを必要とする各クラスに渡したいと思います。これを実装するためのベストプラクティスは何ですか。現在、私は次のようなコードを持っています:-

class db
{
    private $user = 'USER';
    private $pass = 'PASS';
    private $tables = array( 'user','report', 'etc...');

    function __construct(){
        //SET UP CONNECTION AND TABLES
    }
};

class report{
function __construct ($params = array(), $db, $user)
 {        
    //Error checking/handling trimed
    //$db is the database object we created
    $this->db = $db;

    //$this->user is the user object for the logged in user
    $this->user = $user;

    $this->reportCreate();
 }

public function setPermission($permissionId = 1)
{
    //Note the $this->db is this the best practise solution?
   $this->db->permission->find($permissionId)

    //Note the $this->user is this the best practise solution?        
    $this->user->checkPermission(1)

    $data=array();
    $this->db->reportpermission->insert($data)
}
};//end report

私は静的クラスの使用について読んでいて、シングルトンに遭遇したばかりです(これらはすでに古いようですが?)、これを行うための現在のベストプラクティスは何ですか?

5
Stephen

PHPのシングルトンはまったく役に立たず、インスタンスはスクリプトの実行時に作成され、シングルトンかどうかに関係なく、スクリプトが終了すると終了します。これは仕様によるものです。PHPは 何も共有しないアーキテクチャ に従います。

既に行っていることを続けるだけで、奇抜な名前 コンストラクターインジェクション も付いています。 依存性注入 を読んでください。コンストラクターをもう少し堅牢にしたい場合は、 type hinting を検討してください。

class report {
    function __construct (array $params = array(), db $db, $user)
    {        
        ....
    }

    ...
}

参考文献:

7
yannis

Yannis Rizosが言っていることはわかりますが、PHPにデザインパターンを実装するという文脈では無効です。はい、それらは短命であり、私が認めるのは「いくつかの」パターンの使用を制限しますが、それでもあなたがそれらを実装することを妨げない限り、結局のところ、それらはオブジェクト指向パラダイムを使用して行われる「概念」です。

シングルトン(およびファクトリーなど)は、他の言語と同じようにPHPで役立ちます。シングルトンは実際、多くのパターンの中で最も使用されているものの1つであり、他の言語と同じようにPHPでも役立ちます。これは、Yannis Rizosの応答について私を混乱させたものです。したがって、あなた自身のために、特にPHPでのデザインパターンの使用と目的を理解することについての彼の無知は、さらに混乱させるので無視します。

シングルトンは、クラスのインスタンスを1つしか作成できないことを意味します。それだけです。他の言語と同じように、デザインパターンの通常の利点をすべて備えています(ほんの一瞬または数日間実行されるものも含む)-PHPスクリプトをデーモン化して実行することもできます日のためにも)。

次のように実装できます(プライベートコンストラクターに注意してください。複数のインスタンスを防止する上で非常に重要であり、全体で使用されるstaticキーワードにも注意してください)。

class db {

    private static $connection = null;

    /**
    * private so it can ONLY be instantiated from within itself and never created outside of the class - this gives you the control you need
    */
    private function __construct(){
        self::$connection = 'connected'; //replace with the actuall connection to the db code
    }

    /**
    * connects to db and creates instance
    */
    public static function get_instance() {

        if (self::$connection === null) {
            return new self();
        }

        return self::$connection;

    }

    /**
    * access the connection
    */
    public function query($query) {
        return mysql_query($query, self::$connection);
    }

    public function __clone() {
        trigger_error('Can not be cloned.', E_USER_ERROR);
    }

    public function __wakeup() {
        trigger_error('Can not be deserialized.', E_USER_ERROR);
    }

}

//first time used, so will create a NEW connection to the db and store it
$db = db::get_instance();
$db->query("SQL QUERY HERE");

//will NOT create a new connection, but instead use the existing one - this is the singleton pattern because you can only use a SINGLE INSTANCE of the object.
$another_connection = db::get_instance();
$db->query("fdsfdsfsd");
1
HenchHacker