#76 Bug with pear-extend when using more than 1 different DSN


I'm using the latest adodb_lite.

I think there is a bug with the way pear_EXTENDER is created.


2 different DNS (one is MSSQL driven, the second is MYSQL driven)

$dbURI = "mssql://user:pass@host/dbname";
$first = ADONewConnection( $dbURI, 'pear:extend' );

everything works ok

$dbURI = "mysql://user:pass@host/dbname";
$second = ADONewConnection( $dbURI, 'pear:extend' );

this doesn't work, because of the way pear_EXTENDER is created, generic module pear is included only once, thus dbtype is always set to the first DSN.

I don't know how to change this behavior, but I'd really need to use correct modules for both sources.

Any help is greatly appreciated.

Mirko (mirbuf at tin dot it)


  • Mark Dickenson
    Mark Dickenson

    • milestone: --> Next_Version
    • status: open --> closed-fixed
  • Mark Dickenson
    Mark Dickenson

    Logged In: YES
    Originator: NO

    In the adodb.inc.php file find line 75

    include_once ADODB_DIR . '/generic_modules/' . $mod . '_module.inc';

    and change it to

    include ADODB_DIR . '/generic_modules/' . $mod . '_module.inc';

    That should fix your problem.

  • Daniel

    Logged In: YES
    Originator: NO

    I had already tried that change but sorry, it always gives me:

    > Fatal error: Cannot redeclare class pear_ADOConnection in C:\wwwroot\drake\classes\adodb_lite\generic_modules\pear_module.inc on line 128

    I gave up making further edits because my reasonings lead me to a loop about the extender class....

  • Steve Clay
    Steve Clay

    Logged In: YES
    Originator: NO

    The limitation (which should be documented) is that each generic module can be used with only one driver.

    The workaround is a hack, but is incredibly simple: if you need a generic module that has already been used, you just duplicate the module, changing the name slightly in the filename and all references to classnames within. So to use the pear module with a second database driver, you copy pear_module.inc to pear2_module.inc, then open the copy and replace all instances of "pear_" with "pear2_". Your second driver should then use the module "pear2".

    The limitation is due to PHP's lack of multiple-inheritance and mix-ins. ADOdb currently weasles around this by dynamically creating (via eval) intermediate adapter classes [1] to pull module classes into the inheritance chain. There are several ways to implement mix-ins [2], but all require PHP5. In PHP4, the best you could do would be to copy the code of each mix-in (reading the filesystem), combine, and and eval it into a new class. This would work, but you'd lose all benefit of opcode caching. The current system has to use eval, but at least allows the compiled code of each driver and module to be cached.

    [1] http://us.php.net/manual/en/keyword.extends.php#72661
    [2] http://www.achievo.org/blog/archives/46-Mixins-in-PHP.html