Re: Extending PEAR::DB (static constructor issue?)
| From: | bertrand Gugger | Date: | Fri, 10 Mar 2006 10:31:42 +0000 |
| Subject: | Re: Extending PEAR::DB (static constructor issue?) | ||
| References: | 1 2 3 | Groups: | php.pear.general |
| Request: | Send a blank email to pear-general+get-23259@lists.php.net to get a copy of this message | ||
weston@leary.csoft.net wrote:
DB.php is "simply a utility class with some "static" methods for creating DB objects as well as common utility functions for other DB classes." I guess your extensions would have to be on the DB_common which is the real common class for all drivers. (e.g. DB_pgsql extends DB_common) If you extract the essential from the DB::connect() static method, it does something like:However, if you'd actually looked into the connect method you'd know that you don't even get a DB back.Mea culpa. :) My only excuse is that sometimes half the reason we're interested in this OO thing is to be abel to re-use with minimal understanding of the internals of what we're reusing. My sin here probably consisted of innapropriately estimating where the bar for that minimal understanding is....The right way to extend DB would be to extend a specific driver and use that in your DSN. For example, I had a oci8ext driver that I used to add some extra oci8 functions. This of course means that you're making changes specific to the driver, but there is no way to get around this with DB.Is this really true? Couldn't I, for example, hack DB_common instead? Avoiding some of the details relating to the specific databases is part of the reason why I'm trying to come to PEAR::DB... I guess, though, that even if I can add stuff to DB_common, then I'm facing the prospect of merging those every time I want to update. Writing a wrapper around PEAR::DB is starting to seem like the more appealing option. -W Quoting doc header there:
$dsninfo = DB::parseDSN($dsn);
$type = $dsninfo['phptype'];
include_once "DB/${type}.php";
$classname = "DB_${type}";
@$obj =& new $classname;
return $obj;
What means, if you want to extend properly the stuff, then you would have to:
1) overwrite the connect() method in the main DBToyExt extends DB so it uses prefix DBToyExt and not DB (DBToyExt.php)
2) make your extensions in some DBToyExt_common extends DB_common (DBToyExt/common.php)
3) have each driver DBToyExt_xxx extend DBToyExt_common ... AND DB_xxx.
That is simply impossible in PHP: you cannot have multiple heritage.
You can only do something based on Paul's suggestion, around some:
************
* myDB.php *
************
require_once 'DB.php';
require_once 'myDB/common.php';
class myDB extends DB {
function &connect($dsn, $options = array()){
$extraOptions = pullOutExtraFrom($options);
$mydb = & DB::connect($dsn, $options);
$obj = & new myDB_common($mydb, $extraOptions);
return $obj;
}
// same for factory()
....
// eventually extra static methods
....
}
*******************
*myDB/common.php*
*******************
require_once 'DB/common.php';
class myDB_common extends DB_common {
var $mydb;
// eventually extra properties
....
function myDB_common(&$mydb, $extraOptions)
{
$this->DB_Common();
$this->mydb = & $mydb;
doWhatYouWantExtra($extraOptions);
}
// then for *all* standards methods xxxxxx() of DB_Common
// and perhaps for some driver specific ones
function xxxxxx($param...) // reproduce the exact signature of xxxxxx()
{
// eventually some extra specific to your extension but at least:
// take care of eventual return by adress
return $this->mydb->xxxxxx($param...);
}
....
// then have your own methods
function myMethod($param...)
{
// do what you want around $this->mydb} .... } That looks quite heavy, but I believe that once realized, this model could support without any problem some upgrades of pear's DB. Regards -- toggg