OO PHP - 如何创建“通用”数据库对象?

时间:2011-07-27 10:40:38

标签: php oop object

继续我的更高级OO之旅,我正在努力想出能够创建一个名为database的类的最佳方法,该类可以愉快地使用即将被弃用的{{1}命令,mysql_库,以及可能更深层次的其他版本的数据库。

为了简单起见,我希望我的调用代码看起来像这样:

mysqli_

在实例化数据库对象时,那就是我希望指定MYSQL,MYSQLI,MSSQL或者我想稍后添加的任何内容的部分。

我感谢我可以通过在$db = new database("MYSQL", $host,$user,$password,$databaseName); $db->query("SELECT myField FROM myTable"); while ($ROW = $db->fetch_assoc($QRY)) { echo $ROW['myField'] . "<br/>"; } 的每种方法中实施switch块来实现我想要的目标:

database

......但这看起来非常混乱。每次调用class database() { function __construct($type,$host,$user,$password,$databaseName) { $this->dbType = $type; switch ($type) { case "mysql": mysql_dao::connect($host,$user,$password,$databaseName); break; case "mysqli": mysqli_dao::connect($host,$user,$password,$databaseName); break; case "mssql": mssql_dao::connect($host,$user,$password,$databaseName); break; //other cases } } function query($SQL) { switch ($this->dbType) { case "mysql": mysql_dao::query($SQL); break; case "mysqli": mysqli_dao::query($SQL); break; case "mssql": mssql_dao::query($SQL); break; } } function fetch_assoc($SQL) { switch ($this->dbType) { case "mysql": mysql_dao::fetch_assoc($SQL); break; case "mysqli": mysqli_dao::fetch_assoc($SQL); break; case "mssql": mssql_dao::fetch_assoc($SQL); break; } } //other methods.... } 的方法时,代码都会检查它是什么类型,并从另一个对象调用该方法。

所以我的下一个解决方案就是简单地省略database,只使用看起来像这样的调用代码:

database

...所以我们只是为我们正在使用的数据库类型调用数据库访问对象,但我也不喜欢,如果我想将整个项目从mysql转移到mysqli,我会必须寻找所有这些对象引用并进行更改。虽然这在现代PHP编辑器中相当微不足道,但它仍然不觉得它应该是最好的方式(我现在开始理论而不是实用!)

最后,我希望我可以用一个switch语句构建$db = new mysql_dao($host,$user,$password,$databaseName); $db->query("SELECT myField FROM myTable"); while ($ROW = $db->fetch_assoc($QRY)) { echo $ROW['myField'] . "<br/>"; } 类:

database

...然后只需实现一个接口,其中所有其他方法都在各个数据库类型的类中。不幸的是,这不起作用,因为即使class database { function __construct($type,$host,$user,$pass,$db) { switch ($type) { default: case "MYSQL": return new mysql_dao($host,$user,$pass,$db); break; case "MYSQLI": return new mysqli_dao($host,$user,$pass,$db); break; case "MSSQL": return new mssql_dao($host,$user,$pass,$db); break; } } } 的构造函数返回另一个对象的实例,我也无法调用database,因为该方法在数据库对象中不存在。

据我所知,将database->query扩展为database / mysql_dao等类也不对,因为你必须调用扩展类来使用它的方法,我想调用父类,但使用子类的方法。所以这表明mysqli_dao应该扩展database类,但你不能拥有一个有多个潜在父母的子类(可以吗?)

总结 - 我几乎可以肯定我错过了一些东西,而我想要做的事情应该既可能又简单明了,我只是没有想到正确的方法 - 任何人都可以给我一个指针吗? / p>

4 个答案:

答案 0 :(得分:4)

尽管您正在做的事情是重新发明轮子(看看PDO),但一般情况下,对于这样的情况,您可能想要使用像factory pattern这样的东西。

基本伪代码:

$db = Database::create('mysql', $host, ...); // gets a MySQLDatabase object
$db = Database::create('mysqli', $host, ...); // gets a MySQLiDatabase object

答案 1 :(得分:3)

为什么不使用PDO?它提供了与一系列数据库连接的统一方式(它执行的实际查询必须记住目标数据库,但无论您连接的是哪种数据库,API都是相同的)。

答案 2 :(得分:0)

在这种情况下,我一般会:

  • 使用DAOInterfaceconnectquery等方法定义一些fecthAll,...
    • 连接到数据库的所有类都必须实现该接口
    • 表示您的mysql_daomysqli_dao,...将实施该界面

然后,在使用这些课程时,主要优点是:

  • 您稍后会将$dbmysql_dao变为mysqli_dao变量,但始终会获得一个实现DAOInterface的对象
  • 这意味着您可以确保在$db对象上调用所有这些方法


之后,只有一个地方您必须在mysql_daomysqli_dao之间进行选择:当您将这两个中的一个实例化时,将结果分配给$db

然后,如您所知,$db是一个实现DAOInterface的对象,您肯定知道您将始终能够在该对象上调用相同的方法。

答案 3 :(得分:0)

为了使功能具有功能,您需要传递和返回参数作为参考,如下例所示:

 public function &Query($sql){
     $var = mysql_query($sql, $this->connection);
     return $var;
 }

 public function Fetch(&$cur){
     return mysql_fetch_array($cur);
 }

“&amp;”表示变量的引用,而不仅仅是更多文档的副本:http://www.php.net/manual/en/language.references.pass.php

你要做的事情很有效。我创建了接口MySQL数据库,但我确信你会找到一种方法来为不同类型的数据库创建一个对象。