1

据我了解,像 Twig 这样的模板引擎的主要设计思想是从视图中删除所有 PHP 代码,并让呈现视图的控制器设置该视图中所需的所有参数。

然而,想象一个视图由不同的“块”组成:页眉、页脚、购物车和产品列表。您可以让 order_controller.php 检查客户是否登录(因为如果没有,标题不包含“注销”链接),以及获取所有可用产品的列表(以显示它们在产品块),以及在 $_SESSION 中获取购物车的内容(以在购物车块中显示它们)。

然而,让 order_controller 只获取一件事可能更有趣:产品列表。然后,将由控制器呈现的视图将包含其他块(页眉、页脚和购物车)的不同包含,但它们不会包含它们的视图。它们将包括其他控制器(showheader_controller、showfooter_controller 和 showcart_controller),这些控制器反过来会渲染自己的单个块(showheader_controller 只会渲染标题视图等)。简而言之:您将包括在主视图中呈现视图的控制器。然后检查客户是否登录的逻辑将是 showheader_controller,原因很简单,标题视图是唯一需要知道这一点的视图。

这样,您可以拥有大量显示标题的控制器,但不是让每个控制器重复逻辑来检查客户是否登录,而是只将它放在一个地方(呈现标题视图)。如果有一个 Twig 函数可以在视图中的该位置包含任何外部源,那么问题将得到解决(因为我可以只包含其他控制器),但它只允许包含其他模板(不能在其中包含 PHP 逻辑,否则会有点失败)。

我现在解决这个问题的方法是让 order_controller 有这个逻辑:

  • 获取产品列表
  • 启动输出流的缓冲 (ob_start())
  • 包括呈现标题的控制器 (showheader_controller)
  • 将缓冲区的内容存储在变量 $headerView 中。
  • 清理缓冲区
  • 启动输出流的缓冲 (ob_start())
  • 包括呈现购物车的控制器 (showcart_controller)
  • 将缓冲区的内容存储在变量 $cartView 中。
  • 清理缓冲区
  • 冲洗并重复...

在视图中,我打印设置变量的内容:

{{ headerView | raw }}

必须添加原始过滤器,因为 headerView 变量包含 html-tags。

它工作得很好,但并不完全“整洁”。

我的问题:是否有更好的方法来实现这一战略?

4

1 回答 1

3

首先,这可以通过更好地实现 MVC 分离来简化。控制器的工作几乎完全是对事件做出反应,并促使模型对这个事件做出适当的反应。与视图牵手不是控制器的工作,视图也不完全依赖于控制器。

模型是您的核心应用程序,对您的应用程序应该做的所有事情进行建模。视图的工作是可视化应用程序中正在发生的事情,为用户提供与之交互的东西。控制器只是用户和应用程序之间的一点粘合剂,让用户可以控制应用程序。

因此,控制器对诸如“用户访问主页”之类的事件做出反应,触发模型中的必要事件,这会导致视图更新以表示应用程序的新状态。视图可以做它需要做的任何事情。该视图不仅仅是一个 Twig 模板。视图可以与模型对话以获取更多信息。最后,需要向 Twig 模板发送必要数据的不是控制器,而是需要在渲染模板之前为模板设置必要数据的视图。控制器中的代码更少,视图中的代码更多。

如果你想让它更加模块化,你可以定义自定义的 Twig 标签或函数,它们可以从需要获取的任何地方获取必要的数据。例如:

<div class="head">{{ user_login_status() }}</div>

user_login_status是一个 Twig 扩展函数,它可以与模型对话以获取显示状态所需的数据。

希望你能明白。

于 2013-02-28T12:48:00.243 回答