继续我的更高级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>
答案 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)
在这种情况下,我一般会:
DAOInterface
,connect
,query
等方法定义一些fecthAll
,...
mysql_dao
,mysqli_dao
,...将实施该界面然后,在使用这些课程时,主要优点是:
$db
或mysql_dao
变为mysqli_dao
变量,但始终会获得一个实现DAOInterface
的对象$db
对象上调用所有这些方法
之后,只有一个地方您必须在mysql_dao
和mysqli_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数据库,但我确信你会找到一种方法来为不同类型的数据库创建一个对象。