【问题标题】:PHP MVC pattern + REST confusionPHP MVC 模式 + REST 混淆
【发布时间】:2017-10-25 05:44:33
【问题描述】:

我正在开发一个 PHP MVC REST API,如果可以执行调用,它将使用 OAuth 进行身份验证。

所以我的计划是为一个 Angular 2/4 应用程序开发它来处理 API 调用。

这个想法是创建一个结构,其中我的域例如 test.com 将有一个子域 api.test.com。从它的 API 将要求来电。

在我开始构建它之前,我想确认的是我的 MVC 后端结构。

Ref.Pic

  • 模型将拥有所有逻辑
  • View 将是 api.test.com/api/call 演示文稿。在我的情况下输出 JSON。
  • Controller 将接受输入 exmp:api.test.com/api/call 如果调用正确,则调用 Model 中的逻辑。比该调用将对呈现 JSON 的 view 做出反应。它还将持有 OAuth....

我试图理解这个的整个概念,因为我已经尝试过多次构建它并且每次我最终都会遇到一堆乱七八糟的代码。我想看看我对上述项目的理解是否使感觉。

谢谢

【问题讨论】:

  • stackoverflow.com/questions/5863870/… 阅读 tereškos 答案。据我所知,它拥有一切,而不是控制器访问逻辑。所以控制器是验证器并选择要选择的逻辑。如果我错了,请纠正我跨度>
  • @tereško 帮助:D
  • 有道理,你应该看看这个项目github.com/knpuniversity/oauth
  • 谢谢,我会去看看:D

标签: php json rest model-view-controller


【解决方案1】:

当您尝试在代码库中应用SoC 原则时,您会遇到多个问题。

而且,如何处理视图和控制器之间的通信是比较明显的一种。那是因为,如果你把它搞砸了,就没有抽象可以把它全部隐藏起来。

两种主要的方法是Supervising Controller和自治视图(没有文章,但你可以从thisthis中推断出一些)。

监督控制器

这种方法最适合较小的应用程序(嗯 .. 对于较大的“小”值,因为非常小的项目并不真正需要 MVC 的架构膨胀)。它基本上看起来像这样:

/* in a controller */
public function verifyEmail(Request $request)
{

    $identity = $this->search->findEmailIdentityByToken(
        $request->get('token'),
        Identity::ACTION_VERIFY
    );
    $this->registration->verifyEmailIdentity($identity);

    $body = [
        'status' => 'ok',
    ];

    return new JsonResponse($body);
}

本质上,您所拥有的是一个控制器,它与业务模型交互并(在必要时)用数据填充视图。然后它会导致视图被渲染并返回响应。

根据我自己的经验,我发现这是编写后端应用程序时使用的最佳方法,预计只能通过类似 REST 的 API 进行操作。

正如您在示例中看到的那样,这种情况下的“视图”非常微不足道。它基本上是数组,您将其呈现为 JSON(提供的代码实际上会这样做 - 它是从真实项目中复制的)。

注意:
如果您的意图是完全实现 REST as it was proposed(不仅仅是类似 REST 的资源端点)和/或 有resource expansion的功能,那么这种做法可能是错误的,甚至是有害的。

自主视图

当您的表示逻辑变得复杂或必须为具有相同功能的同一应用程序提供不同的 UI(例如,具有网站和 REST API 的单个应用程序,同时具有 xml 和 json 接口),那么使用监督控制器就成了一个球并用链子挂在你的脖子上。您的控制器开始不受控制地增长,您的项目甚至可以在投入生产之前被描述为“遗留代码库”。

这就是您使用这种方法的地方。

您将视图和控制器用作完全独立的类,并在同一层与它们的实例进行交互(例如:引导阶段)。它最终看起来像这样:

/* in /src/application.bootstrap.php */
$command = $request->getMethod() . $parameters['action'];
$resource = $parameters['resource'];

$controller = $container->get("controllers.$resource");
if (method_exists($controller, $command)) {
    $controller->{$command}($request);
}

$view = $container->get("views.$resource");
if (method_exists($view, $command)) {
    $response = $view->{$command}($request);
    $response->send();
}

同样,来自不同实时项目的示例,该项目也使用 DI 容器。在这种情况下,只有一个 UI(因此,在创建视图实例时没有“类型”前缀),这意味着代码可以利用控制器视图之间的 1:1 关系(如果你需要多个 UI)。

这种情况下的控制器基本上只“写入”到模型层。并且视图(也可以从模型层访问服务)仅执行“读取”并提取信息,这是填充模板和呈现模板所需的信息。

而且,如果您的演示逻辑进一步增长,最好开始添加presentation objects,它将包含演示逻辑的重复部分(例如,决定侧边栏中的哪个菜单项必须展开,哪个菜单项子菜单项必须突出显示),这对于多个视图很常见。

如果您的后端应用程序只处理 API,那么这种方法可能过于复杂,除非您正在做“注释”部分中提到的事情之一。

...也许这有点帮助

【讨论】:

    【解决方案2】:

    是的,这是有道理的。我建议改用 Laravel 框架。或者 OctoberCMS 更好。

    【讨论】:

    • 不,我不喜欢使用像 Laravel 这样的框架。听起来很奇怪,但我的思维方式。我尝试编写很多代码,以及我使用的一些框架或库。我不了解整体问题更好。Larvel 因为它本身并没有以严格的方式使用 MVC ......但它是另一个要谈论的话题:D
    • 来吧,Laravel 或 OctoberCMS 为您提供了一个极好的环境,甚至您可以将 OAuth 作为插件安装。这样你就可以集中你的逻辑。类似于您使用模型而不是普通 SQL。
    • 我不使用简单的东西 :D 请没有必要说服我。如果你知道用参考回答问题,请不要再说服我应该使用 Larvel 或 OctoberCMS。
    • 你用不用不关我的事。我说的是这个框架有很多你可能需要建立的特性。
    • Laravel 通常用作仅返回资源的后端服务....
    猜你喜欢
    • 1970-01-01
    • 2010-12-28
    • 2021-12-13
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多