- ベストアンサー
MDB2やDB2の継承の仕方について
- PHPでデータベースへのアクセスでMDB2を使用する際、インスタンスを作らない仕組みと継承させる方法についての質問です。
- MDB2はpearのライブラリを継承して使用することが一般的ですが、自作クラスで継承させるための方法についても知りたいです。
- 質問者はhogeというクラスを作成し、MDB2を継承させて使用したいと考えています。具体的な方法や注意点について教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
(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」となります。 とまあ、ちょっと調べた結果を載せてみました。 分かった事をだらだらと書き綴ったので理解しづらいかもしれませんが・・・。
その他の回答 (1)
- めとろいと(@naktak)
- ベストアンサー率36% (785/2139)
書き忘れです・・・。 全部1から作るなら、MDB2_Driver_mysqlクラスのように MDB2_Driver_Commonを継承してドライバを作ると思います。 私なら面倒なのでしません。「継承したんですよ」ってのが 分かるクラス名にしておけば十分だと思います。 (個人的には。もっとオブジェクト指向に詳しい方からしたら 何と仰るかは不明ですが) 1から作るのはMDB2がサポートしてないDBくらいだと思います。 あと、GoFデザインパターンについての参考URLでも・・・。 http://itpro.nikkeibp.co.jp/article/COLUMN/20051202/225609/
お礼
コードまでご提示いただきましてありがとうございました。 おかげさまで、無事解決することができました。 FactoryMethodにはじめ今回は自分で勉強不足を痛感しました。