number_format(与视图相关的逻辑)在 CakePHP 中应该放在哪里?

Where should number_format (logic relating to the view) go un CakePHP?

经过与同事的讨论,我们认为与视图相关的逻辑应该放在哪里。

例如,假设我们有一个数字要显示在我们的视图中。我认为 number_format(或 CakeNumber::format,因为我们使用的是 CakePHP)应该出现在视图中,因为它与我们显示的内容相关。我的同事认为它应该放在控制器中,因为那是所有逻辑所在。

在这种情况下,我们有两个视图,一个用于网站和最终用户,一个 API 视图,其中 returns 一个 json 响应。如果我要将代码放入控制器中,我必须检查我使用的是哪个视图,以免在 json 响应中给出一个字符串,而实际上它是一个整数。出于这个原因,我非常支持视图中的代码。

问题是,"more" 谁是对的,数字格式应该放在哪里?

除了我关于将代码放入视图的论点之外,他很乐意在视图中使用 htmlentities,但我认为如果我不允许 number_format,他就不能htmlentities 并且应该在控制器中完成。

根据 MVC 的规则,所有逻辑都应该放在模型中,而不是控制器中。控制器应该只将视图需要的所有内容放在一起,然后将其交给要显示的视图。

根据我的经验,View 通常以其中的一小部分逻辑结束。转换格式数字或使用 htmlentities 转义内容最终都是非常小的东西,并且在视图中很好,有些人甚至会考虑使用这些功能作为格式而不是业务逻辑。很多人,包括我自己,都将诸如此类的小功能称为 helpers(正如 Armage 在评论中指出的那样),并且在视图中使用它们是很常见的并且绝对被接受。

这当然是我多年来试图将内容分开并放在正确位置的全部意见,您的里程可能会有所不同。

My colleague things it should go in the controller because that's where all logic goes.

控制器中没有业务逻辑。那不是 MVC。这是一个暴行。

在这种情况下,请始终想象 MVC 主要设计用于的场景:将您的 controller/view 换成另一个界面。例如,想象一下为您的应用程序编写一个命令行客户端,例如执行管理后端任务。您将希望能够在命令行上执行 与您的用户在网站上可以执行的操作相同的操作,例如:

$ admin users create Bob bob@example.com

这在模型中做的事情与网站上的常规用户注册所做的相同,但它需要一个不同的控制器(一个可以处理 CLI 交互的控制器)和一个不同的视图(一个只输出纯文本的视图) .由于您显然不想在编写此代码时重复任何业务逻辑,因此 没有业务逻辑进入控制器 。一定都在模型里。

显然,格式化数字是视图的责任,因为它是视觉上的、人类可读的问题。

如果它是为了操纵数据的呈现方式,那么它应该位于控制器和视图之间的一个层中。您的控制器应该从模型中获取数据,而您的视图应该显示该数据。您的视图可以是任何内容:HTML、PDF、CSV、JSON 等

查看演示者。他们获取一个实体并准备其数据以在视图中呈现。因此,您的视图演示者 class 可以有一个名为 priceFormatted() 的方法,该方法 returns 价格值格式化为小数位、千位分隔符、货币符号等。这样,您可以使用演示者方法在您的 HTML 视图中,但对于其他视图(即 XML 或 JSON),您可以只使用原始值。

For example lets say we have a number that we want to show in our view. I think the number_format (or CakeNumber::format as we're using CakePHP) should go in the view as it's related to what we show. My colleague thinks it should go in the controller because that's where all logic goes.

你哥们说错了。实际上,您应该使用 NumberHelper,它是静态 CakeNumber 的包装器。您通常希望在您的应用程序中避免静态和单例,也可以使用别名帮助程序,因此在视图中使用 NumberHelper。该视图是正确的地方。

In this case we have two views, one for the website and end users and an API view which returns a json response. If I were to put the code in the controller I'd have to check which view I'm using as not to give a string in the json response when really it is an integer. For this reason I'm heavily supporting the code in the view.

控制器无需更改单行即可支持 json 和其他输出。那么,您 可以 使用视图变量的内置序列化 json/xml 或构建自定义 json 视图。 Read this chapter. 然而,没有必要创建两个方法或用实际上错误的业务逻辑填充控制器。

The question is, who is "more" right, where should that number formatting go?

绝对是风景。

控制器应该是瘦的并且不包含任何业务逻辑:

Further to my argument of putting code in the view, he is happy to use htmlentities in the view but I argue that if I'm not allowed number_format, he can't have htmlentities and that it should be done in the controller.

使用 h() 这是 htmlspecialchars() 的快捷方式。并确保将它用于一切 你在那里回应。如果您通过它们传递某些内容,则框架附带的所有核心助手都会在内部为您完成此操作,但请注意可能不会使用它的第三方助手!