[解決済み] PHPのデータベースアクセスでシングルトンを使用するケースはありますか?
質問
私は PDO を介して MySQL データベースにアクセスしています。データベースへのアクセスを設定しているのですが、最初に試したのは以下のようなものでした。
最初に思いついたのは
global
:
$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');
function some_function() {
global $db;
$db->query('...');
}
これは悪しき習慣とされています。少し検索したところ、結局は シングルトン・パターン というのを見つけました。
"は、クラスのインスタンスが1つである必要がある状況に適用されます。
マニュアルの例によると、こうすればいいようです。
class Database {
private static $instance, $db;
private function __construct(){}
static function singleton() {
if(!isset(self::$instance))
self::$instance = new __CLASS__;
return self:$instance;
}
function get() {
if(!isset(self::$db))
self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')
return self::$db;
}
}
function some_function() {
$db = Database::singleton();
$db->get()->query('...');
}
some_function();
こんなことができるのに、なぜあの比較的大きなクラスが必要なのでしょうか?
class Database {
private static $db;
private function __construct(){}
static function get() {
if(!isset(self::$db))
self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');
return self::$db;
}
}
function some_function() {
Database::get()->query('...');
}
some_function();
この最後のものは完璧に機能し、私は
$db
を気にする必要はありません。
どうすればより小さなシングルトンクラスを作ることができるでしょうか、あるいは私がPHPで見逃しているシングルトンのユースケースがあるのでしょうか?
どのように解決するのですか?
さて、私がキャリアを始めたばかりの頃、このことについてしばらくの間悩みました。 さまざまな方法で実装し、静的クラスを使用しないことを選択する 2 つの理由を思いつきましたが、それはかなり大きなものでした。
1つは、絶対に2つ以上のインスタンスを持つことはないと思っていたものが、最終的には2つ目を持ってしまうことが非常によくあることです。 2つ目のモニター、2つ目のデータベース、2つ目のサーバーなど、あらゆるものがあります。
このようなことが起こると、静的クラスを使用していた場合は、シングルトンを使用していた場合よりもはるかに悪いリファクタリングが必要になります。 シングルトンはそれ自体あやふやなパターンですが、インテリジェントなファクトリー パターンにかなり簡単に変換でき、あまり問題なく依存性注入を使用するように変換することさえできます。 たとえば、シングルトンが getInstance() によって取得される場合、それを getInstance(databaseName) にかなり簡単に変更でき、複数のデータベースを使用できるようにすることができます。
2つ目の問題はテストです(そして正直なところ、これは最初の問題と同じです)。 時には、データベースをモックデータベースに置き換えたいと思うことがあります。 事実上、これはデータベースオブジェクトの2番目のインスタンスです。 静的なクラスでこれを行うのは、シングルトンの場合よりもはるかに困難です。静的なクラスのすべてのメソッドではなく、getInstance()メソッドをモックする必要があるだけです(これはいくつかの言語では非常に難しい場合があります)。
人々がグローバルは良くないと言うとき、彼らはそう言う非常に良い理由を持っていますが、それはあなた自身が問題にぶつかるまで常に明白ではないかもしれません。
あなたができる最善のことは、(あなたがしたように)尋ねてから、選択し、あなたの決定の影響を観察することです。 時間の経過に伴うコードの進化を解釈するための知識を持つことは、最初に正しく行うことよりもはるかに重要です。
関連
-
[解決済み】Laravel 5.2 Storage::makeDirectory($dir) でディレクトリが作成されない。
-
[解決済み】file_get_contents( )が動作しない。
-
[解決済み] Uncaught Error: 未定義の関数 mysql_escape_string() の呼び出し。
-
[解決済み] Forbidden :このサーバーの /phpmyadmin にアクセスする権限がありません。
-
[解決済み] PHP 未定義関数への呼び出し
-
[解決済み] libapache2-mod-php7 パッケージの場所がわからない
-
[解決済み] PHPでパスワードをハッシュ化するためにbcryptを使用するにはどうすればよいですか?
-
[解決済み] PHPでユーザー入力をサニタイズするにはどうすればよいですか?
-
[解決済み] PHPを使って現在の年を取得するにはどうすればよいですか?
-
[解決済み】PHPパスワードのハッシュとソルトの安全性について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Fatal error: 未定義の関数 sqlsrv_connect() を呼び出した。
-
[解決済み】++と*+の意味は何ですか?
-
[解決済み】DateTimeクラスのオブジェクトを文字列に変換できない
-
[解決済み】「Fatal error: Class 'MySQLi' not found "を解決するには?
-
[解決済み] SQLSTATE[HY093]: 無効なパラメータ番号: パラメータが定義されていません
-
[解決済み】警告。数値でない値に遭遇しました
-
MacでPHPを実行した際に、メモリサイズが134217728バイトも消費される問題の解決方法について
-
[解決済み】In_arrayが動作しない。
-
[解決済み] シングルトン・パターンの欠点やデメリットは何ですか?[クローズド]
-
[解決済み】PHP5でSingletonデザインパターンを作成する