![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
PHPでデータベースへのアクセスでMDB2を使っています。
よくpearのライブラリを継承して使うのですが、MDB2の場合下記(1)のようにインスタンスを作らない仕組みなのでしょうか?
(2)のようにMDB2を継承させて使うにはどのようにしたらよいのでしょうか?
(1)
$mdb2 =& MDB2::factory(CONFIG_DB_DSN);
$res =& $mdb2->query("SELECT * FROM users LIMIT 5");
(2)
$hoge = new hoge;
$res =& $hoge->query("SELECT * FROM users LIMIT 5");
class hoge extends MDB2 {
function query() {
echo "オーバーライドされない";
}
}
誰がご存じの方いらっしゃれば、ご教示いただければ幸いです。
No.1ベストアンサー
- 回答日時:
(1)のパターンを、GoFデザインパターン「FactoryMethod」と呼びます。
factory()メソッドは、渡されたパラメータにより、戻り値とする『インスタンス化
されたオブジェクト』を切り替えます。
インスタンス化はfactory()を行った時点でされます。
よって、(2)のような明示的なインスタンス化は不要となります。
その上で、MDB2はMySql、PostgreSQL、SQLiteなどいろんなDBに対応しているようです。
色んなDBに対応するということは、操作が一緒でないと困ります。
なぜならDBが変わった途端に今まで作った操作が水の泡になっては問題だからです。
そこで、GoFデザインパターン「AbstractFactory」が利用されています。
それを利用する事で、「FactoryMethod」で受け取った戻り値は利用者には何のクラスの
オブジェクトなのかは不明ですが、どのクラスのオブジェクトだとしても以降の
呼び出すメソッドや手順が全く一緒となります。
MDB2を詳しく使ったことがないので不明ですが、factory()に渡す
パラメータはそれだけではないのでは?
そのオブジェクトは『メソッド名が全く一緒なので、利用者は以降の各
メソッドの呼び出しはパラメータに依存しない』事になります。
そういったインターフェースを利用したような形で、利用者が
欲しいクラスオブジェクトを受け取れ、以降の操作を一切変えなくても
良い仕組みになっています。
継承するのはMDB2クラスではありません。
PEARクラスを継承しているMDB2_Driver_Commonクラスになります。
(query()メソッドがあるのはMDB2.php内にあるMDB2_Driver_Commonクラス)
mysqlドライバのクラス(MDB2_Driver_mysqlクラス)を見てみるとMDB2_Driver_Commonを継承しています。
しかし、MDB2_Driver_Common自体を継承する事はできません。
なぜならfactory()で生成されているオブジェクトはMDB2_Driver_Commonクラスではなく
MDB2_Driver_mysqlクラスだからです。
よって、継承するのはMDB2_Driver_mysqlクラスになります。
<?
require("MDB2.php");
require("MDB2/Driver/mysql.php");
class MDB2_Driver_mysqlExt extends MDB2_Driver_mysql {
function &query($query, $types = null, $result_class = true, $result_wrap_class = false)
{
echo "<b>extends class</b><br />";
return parent::query($query, $types, $result_class, $result_wrap_class);
}
}
define('CONFIG_DB_DSN', 'mysqlExt://root:root@localhost/mysql');
$mysqlExt = MDB2::factory(CONFIG_DB_DSN);
$result = $mysqlExt->query("show tables");
while (($row = $result->fetchRow())) {
echo $row[0] . "<br />";
}
$mysqlExt->disconnect();
今回の例ではMySQLになります。
継承するということは別のドライバを作成する事になりますので、
上の例だと、/MDB2/Driver/配下にmysqlExt.phpファイルで以下のような
クラスを定義しておくことで実現できます。
require("MDB2/Driver/mysql.php");
class MDB2_Driver_mysqlExt extends MDB2_Driver_mysql {
function &query($query, $types = null, $result_class = true, $result_wrap_class = false)
{
echo "<b>extends class</b><br />";
return parent::query($query, $types, $result_class, $result_wrap_class);
}
}
継承したドライバ名称は「mysql」ではありませんから、当然
dsnも変わります。
dsnのドライバ名についてはクラス名「MDB2_Driver_mysqlExt」の
「MDB2_Driver_」以降の文字列となります。
ドライバ名にアンダーバー(「_」)があればあるほど、それがディレクトリとなっていきます。
つまり、クラス名が「MDB2_Driver_mysql_Ext」であったとき、
クラスを探しにいくのはMDB2\Driver\mysql\Ext.phpとなり、
dsnのドライバ名も「mysql_Ext」となります。
とまあ、ちょっと調べた結果を載せてみました。
分かった事をだらだらと書き綴ったので理解しづらいかもしれませんが・・・。
コードまでご提示いただきましてありがとうございました。
おかげさまで、無事解決することができました。
FactoryMethodにはじめ今回は自分で勉強不足を痛感しました。
No.2
- 回答日時:
書き忘れです・・・。
全部1から作るなら、MDB2_Driver_mysqlクラスのように
MDB2_Driver_Commonを継承してドライバを作ると思います。
私なら面倒なのでしません。「継承したんですよ」ってのが
分かるクラス名にしておけば十分だと思います。
(個人的には。もっとオブジェクト指向に詳しい方からしたら
何と仰るかは不明ですが)
1から作るのはMDB2がサポートしてないDBくらいだと思います。
あと、GoFデザインパターンについての参考URLでも・・・。
http://itpro.nikkeibp.co.jp/article/COLUMN/20051 …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHP MySql ページング 2 2022/09/20 06:38
- PHP PHPでMysqlにデータがあるかどうか判別したい 1 2023/03/02 11:48
- HTML・CSS 全部のアクセスを指定したページに転送させたい 2 2022/06/28 16:33
- PHP php my adminより取り出したデータ表示 2 2022/06/15 11:56
- MySQL SQLです。下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「昨年の各月の総降 1 2023/07/01 00:32
- Windows 10 バッチファイルの記述法とルールについてアドバイスをお願いいたします。 1 2022/04/13 10:50
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- PHP PHP一覧表示した項目にリンクをはりたい 1 2023/07/12 17:08
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
PHP4、PHP5 1ファイル複数クラ...
-
MDB2やDB2の継承の仕方について
-
PHPのクラス名の付け方
-
php、可変プロパティ名について
-
PHPの名前空間について質問です。
-
フォルダ関連のライブラリにつ...
-
'_'(アンダースコア)の使い方...
-
正規表現について
-
-> について教えてください
-
「PEAR::Auth認証」の結果によ...
-
【PHP】privateな静的メソッド...
-
ワードプレスではPHPをどこまで...
-
formで入力された情報を次のペ...
-
php初心者がWordPressを理解す...
-
【BAT(バッチ)ファイル】Web...
-
PHP8を使うと、大量のWarningが...
-
onedrive にexcelファイルをア...
-
文字化けに関して
-
ヒアドキュメントを中断してinc...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
ラッパークラスって何ですか?
-
class定義のphpをファイル分割...
-
PHPの名前空間について質問です。
-
配列とオブジェクトの違い
-
phpのクラスにて別ファイルの変...
-
PHP4、PHP5 1ファイル複数クラ...
-
文字連結中の三項演算子について
-
PHP5 コンストラクタや初期化の...
-
プログラムにも慣例みたいなも...
-
phpで使用不可のクラス名
-
(クラス関連)staticキーワー...
-
phpにおける初期化の意味
-
PHPでサブクラスからスーパクラ...
-
クラス
-
phpで時間を増やしていくにはど...
-
[CakePHP2.2] :: の意味と役割
-
Objectの型チェック
-
ユーザー定義関数とクラスの違...
-
'_'(アンダースコア)の使い方...
おすすめ情報