MVC PHP:视图循环或控制器循环中的数据操作(即 1 个循环或 2 个循环)

发布于 2024-12-05 17:24:33 字数 381 浏览 1 评论 0原文

一直困扰我的一件事是执行多个循环来操作数组。

我的意思是,在控制器中,数据是通过模型从数据库中获取的。假设我们显示一个用户列表,每个用户都有一个状态(1、2、3 分别相当于已验证、未验证、禁止)。在循环的每次迭代中,将通过另一个数据库查询检查并显示状态(忘记本例中的 mysql 连接)。

现在,您是否会在循环中的控制器中执行此操作,然后在视图中执行另一个循环,其中所有数据已获取并预先形成以供显示(因此导致 2 个循环)。

--或者--

您是否会在视图中执行此操作,从而导致一个循环,但会从视图调用模型。我知道这在严格的 MVC 模式中是可以的,但通常不受欢迎。

循环两次似乎很愚蠢,但它更整洁,因为所有数据操作都保存在控制器内。

Something that has always bothered me is doing more than one loop to manipulate an array.

What I mean is, in the controller the data is fetched from the DB via a model. Lets say we are showing a list of users, and each user has a status (1,2,3 equates to verified, unverified, banned respectively). Within each iteration of the loop the status would be checked and displayed via another Db query (forget mysql joins in this example).

Now, would you do that in the controller within a loop, and then perform another loop in the view with all the data already fetched and pre-formed ready for display (therefore resulting in 2 loops).

--OR--

Would you just do it in the view therefore resulting in the one loop but with model calls from the view. I understand that this is ok in the strict MVC pattern but its frowned upon generally.

It seems silly to loop twice but then its tidier as all the data manipulation is kept within the controller.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

找回味觉 2024-12-12 17:24:33

我不会在视图或控制器中而是在模型上这样做。

我解释一下:

  • 你的控制器的工作是检索预期的用户列表,检查 ACL 等...
  • 你的视图的工作是以优雅的形式呈现这些数据
  • 。你的模型工作是从数据库中获取/存储数据并确保完整性。 Userstatus 对我来说也是一个模型。

我的配置使这变得非常简单,我使用 Mustache(Php 端口)进行视图,这允许我直接在视图中调用模型中的方法。我为我的模型编写了自己的 ORM,这样我就有了包装器。

这样的代码对我来说是这样的:

// Controller
$template = new Template('pages/users.html');
$template->users = mUser::find(); // return array of mUsers instances
echo $template->render();

// View
{{#users}} <!-- For each user -->
  {{getName}} has status {{#getStatus}}{{getStatusName}}{{/getStatus}}<br />
  <!-- getStatus is a method from mUser model, that return a mUserStatus instance -->
{{/users}}

/* More explain on the view syntax
{{name}} = $user->getName() (return string)
{{getStatus}} = $user->getStatus() (return instance of mUserStatus);
{{statusName}} = $user->getStatus()->getStatusName();
*/

您可能希望在请求级别为每个模型实例进行请求缓存,以便在不需要时永远不会运行请求两次。

对我来说,这似乎比将其委托给控制器更自然。我尝试将商业智能放在控制器上,不需要智能也不需要程序员干预来检索每个用户的状态名称。

我希望它有帮助。

I would do that nor in the view or the controller but on the model.

I explain :

  • Your controller's job is to retrieve the expected user list, check ACL, etc...
  • Your view's job is to present this data in an elegant form
  • Your Model job's in to fetch/store data from Database and ensure integrity. Userstatus is a model too for me.

My configuration make this pretty easy, I use mustache (Php port) for view, which allow me to call methods from my models directly in view. I wrote my own ORM for my models, that way I have wrappers.

Such code would look like that for me :

// Controller
$template = new Template('pages/users.html');
$template->users = mUser::find(); // return array of mUsers instances
echo $template->render();

// View
{{#users}} <!-- For each user -->
  {{getName}} has status {{#getStatus}}{{getStatusName}}{{/getStatus}}<br />
  <!-- getStatus is a method from mUser model, that return a mUserStatus instance -->
{{/users}}

/* More explain on the view syntax
{{name}} = $user->getName() (return string)
{{getStatus}} = $user->getStatus() (return instance of mUserStatus);
{{statusName}} = $user->getStatus()->getStatusName();
*/

You may want to have request caching for each model instances in request level so that you never runs a request twice times if not needed.

That seems more natural to me than to delegate it to controller. I try to put business intelligence on controllers, there is no need for intelligence nor programmer intervention to retrieve a status name for each user.

I Hope it help.

神经大条 2024-12-12 17:24:33

在我看来,操作您返回的数据的逻辑应该位于控制器中。操作数据表示的逻辑可以位于视图中。
所以我会选择第二个选择。

但是,正如您自己指出的那样,这是一种实施选择。

另请注意,多次往返数据库不利于性能。您的示例是一个典型的 n+1 问题,这意味着您有 1 个“顶级”选择查询,然后针对第一个结果集中的每一行有 N 个查询。如果您遇到此类问题,请务必尝试在数据库级别解决它们。

我想添加的另一个注释是,在您的示例中,您将状态说明存储在数据库中。如果您想以其他语言提供应用程序,这可能会成为一个问题。但这超出了你的问题范围:)

In my opinion logic that manipulates the data you're returning, should be located in the controller. Logic that manipulates the representation of your data can be located in the view.
So I would go for the second option.

But, as you pointed out yourself this is a choice of implementation.

Also note that multiple round trips to your DB are bad for performance. Your example is a typical n+1 problem, meaning that you have 1 'top' select query and then N more queries for each row in your first result set. If you encounter such a problem always try to solve them on the DB level.

Another note I would like to add is that in your example you're storing status explanations in the DB. If you want to provide your applications in other languages, this might prove to be a problem. But this is beyond the scope of your question :)

往事风中埋 2024-12-12 17:24:33

做两个循环是干净的方法。这就是我在大多数情况下会做的事情,但我认为对此没有通用的答案。就像如果您有大量数据并且性能出现问题,最好忘记 MVC 并只使用一个循环。

第三种方法是使用可以从视图调用的辅助函数。现在想来……这或许是最好的办法了。

Doing two loops is the clean way. That is what I would do for most cases, but I think there is no gerneral answer to this. Like if you have a lot a data and performance gets an issue it would be better to forgett about MVC and just use one loop.

A third way would be to use a helper function you can call from the view. Now that I think about it... that would probably be the best way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文