gpt4 book ai didi

php - 这是用于数据库实现的良好 PHP OOP 结构吗?

转载 作者:搜寻专家 更新时间:2023-10-30 23:13:49 26 4
gpt4 key购买 nike

我有一系列的类(class):

abstract class Database extends PDO {}
abstract class OracleDatabase extends Database {}
abstract class MySQLDatabase extends Database {}
abstract class MSSQLDatabase extends Database {}

然后,当我想要一个数据库连接的实例时,我创建了一个新类,它扩展了 OracleDatabaseMySQLDatabaseMSSQLDatabase,具体取决于关于数据库所在的位置...例如

class MyAppDatabase extends OracleDatabase {}

首先,这是一个好的设计吗?我读到过使用接口(interface)比扩展抽象类更好,但我不确定如何在不重复代码的情况下做到这一点。

我确实意识到 PDO 的全部意义在于摆脱特定于 DB 的代码,但是对于诸如 DB 对象括号之类的事情,我仍然需要不同的功能(例如,在 Oracle 中,您使用双引号;在 MySQL 中,您使用反引号)、数据类型检测(user_tab_columns vs INFORMATION_SCHEMA)等

而且 - 如果我想创建一个名为 Updater 的类,它允许客户端为特定表创建一组多个“更新” - 对 SET 和 WHERE 子句使用相同的字段,但是不同的值(value)观?我不认为我能够从 Database 类继承,所以我是否可以将它设为一个“具有”数据库对象的独立类?

class Updater {

private $db;

private $table;

private $setFields;

private $whereFields;

private $updates;

function __construct($db, $table, $setFields, $whereFields) {
if (!($db instanceof Database)) {
if (is_scalar($db)) {
$type = gettype($db);
} else {
$type = get_class($db);
}
throw new Exception("Expected Database object; " . $type . " found.");
}

$this->db = $db;

// ensure $table is a table in the database
// ensure $setFields and $whereFields are columns in the table

$this->table = $table;
$this->setFields = $setFields;
$this->whereFields = $whereFields;
$this->updates = array();
}


function addUpdate($setValues, $whereValues) {

// ensure $setValues is an array and has the same cardinality as
// $this->setFields

// ensure $whereValues is an array and has the same cardinality as
// $this->whereFields

array_push($this->updates,
array(
'setValues'=>$setValues,
'whereValues' => $whereValues
)
);
}

function doUpdate() { // without error handling

$escTable = $this->db->bracket($table);

$setTemplate = array();

foreach ($this->setFields as $setField) {
$escField = $this->db->bracket($setField);
$colonField = makeColonField($setField); // :fieldName
$setting = "$escField = $colonField";
array_push($setTemplate, $setting);
}

$csvSetTemplate = implode(", ", $setTemplate);

$whereTemplate = array();

foreach ($this->whereFields as $whereField) {
$escField = $this->db->bracket($whereField);
$colonField = makeColonField($setField); // :fieldName
$setting = "$escField = $colonField";
array_push($whereTemplate, $setting);
}

$andedWhereTemplates = implode(" AND ", $whereTemplate);

$sql = "UPDATE $escTable SET $csvSetTemplate WHERE $andedWhereTemplates";

$sth = $this->db->prepare($sql);

foreach ($this->updates as $update) {

$setValues = $update['setValues'];
$whereValues = $update['whereValues'];

$params = array();
for ($i=0; $i<count($setValues); $i++) {
$setField = $this->setFields[$i];
$setValue = $setValues[$i];
$colonField = makeColonField($setField);
$params[$colonField] = $setValue;
}

for ($i=0; $i<count($whereValues); $i++) {
$whereField = $this->whereFields[$i];
$whereValue = $whereValues[$i];
$colonField = makeColonField($whereField);
$params[$colonField] = $whereValue;
}

$sth->execute($params);
}
}
}

这是一个好的解决方案吗?

最佳答案

首先,我建议在这种情况下抽象类更好,因为不同的RDBMS之间通常有很多共同点,你可以写一些共同的方法来更清楚地解决问题。

还有另一种方法:

class Database extends PDO {
private $engine; //this is a DBEngine
}

interface DBEngine
{
}

class MySQLEngine implements DBEngine
{

}

class MSSQLEngine implements DBEngine
{

}

...

在这种情况下,您可以使用接口(interface),因为通用方法在数据库中实现,而每个引擎只是实现在 RDBMS 之间具有不同行为的方法。

这称为适配器模式,您可以在 CodeIgniter 的源代码中阅读一些相关内容:http://ellislab.com/codeigniter .

对于第二个问题,您可以在类数据库中实现更新方法。

换句话说,使“更新”成为类数据库的公共(public)成员。

关于php - 这是用于数据库实现的良好 PHP OOP 结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16966892/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com