我应该在MVC中完全分离模型和ORM吗?

F21*_*F21 6 php model-view-controller orm model

我正在使用PHP的MVC应用程序,它没有使用任何框架.我正在使用RedBean来实现我的ORM,它实现了数据映射器模式,并且与doctrine类似.

根据这个问题,我理解该模型不是ORM对象.在我的项目中,我有以下场景:

  • 需要与数据库中的许多表进行通信的"复杂"模型:

    • 其中一个模型可能类似于RBAC权限系统.控制器应该能够调用类似的内容$permission->isAllowed($controller, $action, $resource)来确定是否允许用户执行所请求的操作.此外,他可能会调用$permission->getPermissions()以获取用户拥有的权限列表.
  • "简单"模型,其中模型通常可以由数据库中的1个表表示:

    • 一个这样的模型就是User模型.例如$user->changeRank(),$user->addPoints()依此类推.

我现在面临的问题是查看各种框架的大多数文档,我可以看到在示例中,控制器直接与ORM进行通信.例如,这是symfony2的示例控制器:

public function createAction()
{
    $product = new Product();
    $product->setName('A Foo Bar');
    $product->setPrice('19.99');
    $product->setDescription('Lorem ipsum dolor');

    $em = $this->getDoctrine()->getEntityManager();
    $em->persist($product);
    $em->flush();

    return new Response('Created product id '.$product->getId());
}
Run Code Online (Sandbox Code Playgroud)

如果ORM不是模型,为什么允许控制器直接与它交互?它不应该与看起来像这样的模型相互作用吗?

class ProductModel{
   public function newProduct($name, $price, $description){
        $product = new Product();
        $product->setName('A Foo Bar');
        $product->setPrice('19.99');
        $product->setDescription('Lorem ipsum dolor');

        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($product);
        $em->flush();
   }
}
Run Code Online (Sandbox Code Playgroud)

最后,我permissions先前概述了模型.这被认为是MVC背景下的模型吗?此类将在整个应用程序中使用,因为大多数abctions都需要检查访问权限.

Mik*_*ell 2

ORM(对象关系映射器)用于生成模型文件。模型文件用于应用程序和数据库(模型)之间的通信。看起来你很熟悉 ORM 流程,但是对于那些可能不熟悉的人来说,快速回顾一下(以理论为例),我可能会很幸运地回答你的问题。

您使用 ORM 内省数据库模式,这会生成模式文件。现在,使用此架构文件,您可以更改它以满足您的应用程序需求。例如,您可以添加 actAs: { Timestampable ~}、 或actAs: NestedSet: hasManyRoots: true。此外,您还需要使用此模式文件来设置您希望对象之间关系的行为方式(即 1:M、M:M 使用 arefClass等)

一旦您的架构文件准备就绪,您就可以发出命令来生成模型文件。模型文件是您可以在应用程序中使用来访问数据库的类。因此控制器实际上是通过 ORM 生成的文件与模型(您的数据库)进行通信。

您给出的示例是一个很好的示例,因为您可以将大部分业务逻辑从操作(页面控制器)中卸载到模型中。这样,可以从其他代码点访问相同的逻辑,而无需处理任何控制器级逻辑。学说的作用(以及推进的作用)是允许您创建“表”(或“对等”)类。这些类充当处理多个对象的容器。您应该在这些类中添加业务逻辑,如第二个示例中所示。

最终目标是使您的操作尽可能轻量级,只需处理请求参数和表单处理,然后通过“表”或您设计的自定义类将值推送到您的模型。遵循这个范例,您可以拥有一个功能丰富的应用程序,具有精简的操作和集中的业务逻辑。

编辑 - -

抱歉,我错过了您关于权限 API 的最后一个问题。从您发布的内容来看,它似乎遵循 MVC 范例,因为您有一个权限对象并用作控制器和数据库之间的 API。