gpt4 book ai didi

PHP MVC 模型关系 - MySQL

转载 作者:行者123 更新时间:2023-11-30 22:04:42 27 4
gpt4 key购买 nike

我正在构建一个小而简单的 PHP 内容管理系统,并选择采用 MVC 设计模式。

我很难理解我的模型应该如何与数据库结合使用。

我想将数据库查询本身分开,这样如果我们将来选择更改数据库引擎,就很容易做到。

作为一个基本概念,下面提出的解决方案是否可行,是否有更好的做事方式,这种方法有什么缺陷?

首先,我有一个数据库类来处理所有 MySQL 特定的代码片段:

class Database
{
protected $table_name;
protected $primary_key;

private $db;

public function __construct()
{
$this->db = DatabaseFactory::getFactory()->getConnection();
}

public function query($sql)
{
$query = $this->db->prepare($sql);
$query->execute();
return $query->fetchAll();
}

public function loadSingle($id)
{
$sql = "SELECT * FROM $this->table_name WHERE $this->primary_key = $id";
return $this->query($sql);
}

public function loadAll()
{
$sql = "SELECT * FROM $this->table_name";
return $this->query($sql);
}
}

其次,我有一个模型,在这种情况下可以容纳我所有的菜单项:

class MenuItemModel
{
public $menu_name;
public $menu_url;

private $data;

public function __construct($data)
{
$this->data = $data;
$this->menu_name = $data['menu_name'];
$this->menu_url = $data['menu_url'];
}
}

最后,我会有一个“工厂”将两者结合在一起:

class MenuItemModelFactory extends Database
{
public function __construct() {
$this->table_name = 'menus';
$this->primary_key = 'menu_id';
parent::__construct();
}

public function loadById($id)
{
$data = parent::loadSingle($this->table_name, $this->primary_key, $id);
return new MenuItemModel($data);
}

public function loadAll()
{
$list = array();
$data = parent::loadAll();
foreach ($data as $row) {
$list[] = new MenuItemModel($row);
}
return $list;
}
}

最佳答案

您的解决方案当然可行,但存在一些缺陷。

  1. Database 类在其构造函数类 DatabaseFactory 中使用 - 这并不好。 DatabaseFactory 必须自己创建Database 对象。不过这里没问题,因为如果我们查看 Database 类,我们会发现它不是数据库,它是某种 QueryObject 模式(参见 link更多细节)。所以我们可以通过将类 Database 重命名为更合适的名称来解决这里的问题。

  2. MenuItemModelFactory 正在扩展类 Database - 这不好。因为我们已经决定,Database 只是一个查询对象。所以它必须只包含一般查询数据库的方法。在这里,您将创建模型的知识与一般的数据库查询相结合。不要使用继承。只需在 MenuItemModelFactory 中使用 Database(查询对象)的实例来查询数据库。所以现在,如果您决定迁移到另一个数据库并更改 SQL 语法,您只能更改“数据库”的实例。类 MenuItemModelFactory 不会因为迁移到新的关系数据库而改变。

  3. MenuItemModelFactory 不适合命名,因为 DDD(领域驱动设计)中的工厂目的是隐藏创建实体或聚合的复杂性,当它们需要许多参数或其他对象时。但是在这里你并没有隐藏创建对象的复杂性。您甚至没有“创建”对象,而是从某个集合中“加载”对象。

所以如果我们把所有的缺点都考虑进去,改正过来,就会得出这样的设计:

class Query
{
protected $table_name;
protected $primary_key;

private $db;

public function __construct()
{
$this->db = DatabaseFactory::getFactory()->getConnection();
}

public function query($sql)
{
$query = $this->db->prepare($sql);
$query->execute();
return $query->fetchAll();
}

public function loadSingle($id)
{
$sql = "SELECT * FROM $this->table_name WHERE $this->primary_key = $id";
return $this->query($sql);
}

public function loadAll()
{
$sql = "SELECT * FROM $this->table_name";
return $this->query($sql);
}
}

class MenuItemModel
{
public $menu_name;
public $menu_url;

private $data;

public function __construct($data)
{
$this->data = $data;
$this->menu_name = $data['menu_name'];
$this->menu_url = $data['menu_url'];
}
}

class MenuItemModelDataMapper
{
public function __construct() {
$this->table_name = 'menus';
$this->primary_key = 'menu_id';
$this->query = new Query();
}

public function loadById($id)
{
$data = $this->query->loadSingle($this->table_name, $this->primary_key, $id);
return new MenuItemModel($data);
}

public function loadAll()
{
$list = array();
$data = $this->query->loadAll();
foreach ($data as $row) {
$list[] = new MenuItemModel($row);
}
return $list;
}
}

也可以考虑阅读以下内容:

关于PHP MVC 模型关系 - MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42156468/

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