PHP MVC中的基本模型,好还是坏?

PHP MVC中的基本模型,好还是坏?,php,model-view-controller,Php,Model View Controller,我正在用PHP编写自己的MVC框架,只是为了学习。有一个router/dispatcher类来调用正确的控制器/操作并不难 但现在我要做的是使用模型。或者实际上是模型层。但有件事让我困惑 许多其他MVC框架都有一个“BaseModel”。我读到过,这实际上是一种糟糕的做法,因为“模型”不应该被视为另一门课。但作为一个真正的“层”,它可以包含“映射器”模式或“存储库”模式等内容 但老实说,我不认为这有什么好处。对我来说,“BaseModel”类似乎是最快的方法,结果也是一样的 我可以做一些简单的事

我正在用PHP编写自己的MVC框架,只是为了学习。有一个router/dispatcher类来调用正确的控制器/操作并不难

但现在我要做的是使用模型。或者实际上是模型层。但有件事让我困惑

许多其他MVC框架都有一个“BaseModel”。我读到过,这实际上是一种糟糕的做法,因为“模型”不应该被视为另一门课。但作为一个真正的“层”,它可以包含“映射器”模式或“存储库”模式等内容

但老实说,我不认为这有什么好处。对我来说,“BaseModel”类似乎是最快的方法,结果也是一样的

我可以做一些简单的事情,比如:

class User extends BaseModel
{
    // the GetUserBy* could easily be something that's handled by the
    // BaseModel class, like in the Repo pattern.

    public function getUserByName ( $name )
    {
        // no error handling of any kind, just for simplicity
        return $this->db->exec("SELECT * FROM users WHERE name='".$name."'");
    }

    // $data = array
    public function saveUser ( $data )
    {
        // Make sure no extra fields are added to the array
        $user = array ( 'name' => $data['name'],
                        'address' => $data['address']);

        $this->db->autoSave ( $user );
    }
}
但如果我选择存储库模式,那么我必须创建以下内容: 存储库 实体 刀

实体已聚合到其他存储库。所以基本上我是手动将整个数据库方案写入对象

最后,有什么区别???除了我可能通过简单地使用BaseModel类节省了很多时间之外

但是为什么它仍然被认为是一件坏事呢??这并不是说回购模式比我现在做的更多地解耦了我的应用程序。因为对我来说,上面提到的那些模式似乎被高估了。它可能只在具有共享状态的应用程序中工作;将对象保存在本地(存储库中)并稍后提交

这就是为什么我认为没有人能真正回答这个问题


但我仍然希望看到一个像样的答案,让我走:“啊……我在想什么……”。但是如果不是这样,那么我确信BaseModel一点也不坏,大多数博客作者只是一群羊:-)

模型应该是抽象的,只定义方法而不实现它们。至于您的
用户
模型,您可以轻松编写一个接口
获取用户
,该接口将具有所有这些功能,并在
用户
模型上实现这些功能。

我根本不会使用基本模型,因为您的大多数模型都没有一个统一的接口,它们应该遵守。如果愿意,您可以为许多不同类型的模型(这只是基本的面向对象编程)创建基类

总的来说,我认为模型应该是“松散”的组件,您可以用一个控制器连接在一起,并显示一个或多个视图。它们不能真正拥有一个统一的接口,因为它们都会做不同的事情:一些甚至可能不会与持久性存储进行通信,一些可能不是持久性的,和/或一些可能由其他模型组成

这并不是说回购模式使我的应用程序与我的 现在做什么

应用程序与SQL数据库组件紧密耦合(实际上,SQL数据库组件充当映射器)。然而,尽管如此,您的设计更像是一种方法,而不是一种方法(这可能是您提到的大多数博客作者所抱怨的)

活动记录不仅封装了数据,还封装了数据库访问:

$user = new User();
$user->setUsername('jane');
$user->setEmail('jane@foo.bar');
$user->save();
最好让记录对象不知道持久性层(关注点分离)。您的“base”只是通过返回用户数据数组来实现这一点,当这些数组被修改时,它们必须被传递回用户“base”进行保存。您可以将命名更改为:

class UserRepo extends BaseRepo
{
    // user-specific repo code...
}

$userRepo = $this->getRepo('User');
$user = $userRepo->getUserByName('jane');
$user['email'] = 'jane@new.email';
$userRepo->save($user);

拥有一个基本回购协议没有什么错。

如果您试图从PHP框架中学习好的MVC实践,那么您就错了。即使是PHP中最好的框架也充满了设计错误和缺陷

具有“BaseModel”的框架通常实现某种ORM。这里最流行的模式是ActiveRecord。它适用于简单的表,与其他表没有关系(基本上是美化的getter/setter)。但在处理更复杂的结构和查询时,它开始崩溃。通常引起广泛的疾病

另一个原因,即这种方法导致问题的原因,是在这种情况下,您的“模型”有太多的责任。您的业务逻辑与存储紧密绑定,存储与逻辑焊接在一起。随着应用程序的增长,此类“模型”将积累黑客


不,“一群博主”不是羊。他们刚刚读过关于应用程序架构和面向对象编程的书。你上一次读这方面的书是什么时候?

看起来不错-你能给我们一个链接到这些博客帖子吗?@Alp代码示例?推进只是一个ORM,我不会朝那个方向走,因为我喜欢自己写查询。我真的不恨你。但我也不想用它们。一些“魔法”是可以的,但不会太多。但这是一个完全不同的故事。是的,看起来确实像推进-但我有偏见,我爱推进!我无法想象没有一个row类的基类——至少在特性在PHP开发中很常见之前是这样。这是一个非常书生气的回答,没有一个陈述会有一个像样的解释。此外,如果模型类只定义方法而没有任何实现逻辑,那么它应该是一个接口,而不是抽象的。正如我所说,我知道我可以“轻松地”将其划分为模型、抽象类和接口。但是,与一个基本模型相比,它有什么好处呢。看起来你甚至都没试着回答这个问题。@Vivendi-这个问题很有趣,但请礼貌一点。“事实已经存在了一段时间了,正如代表所证明的,你是新来的。@halfer抱歉,我希望没有人对我的回答感到生气。”。无论如何,我不是有意粗鲁的。我应该用另一种方式在我的评论中加入某些东西。我想你是对的。在某种程度上,它看起来确实像一种回购模式。但我没有使用任何实体类或值对象。正如我在文章中也说过的,这感觉很像是将数据库方案重写为“对象”我的“UserRepo”只返回数组d