【发布时间】:2015-07-06 10:39:00
【问题描述】:
我正在使用 Laravel,带有 Eloquent,默认 ORM。
文档暗示 ORM 调用在控制器中很好,但这并不正确。
例如,假设我想获得一个用户。 User::findOrFail($id) 是我需要的代码。 documentation 在 Controller 中有这个。
想象一下,我在整个项目的 100 个地方都有这段代码,我需要再对它进行检查,也许是为了让用户的帐户也有标记。这有点麻烦,但如果它在模型中,我会简单地更新模型方法。
此实例中的示例模型方法:
function get_user_by_id($id)
{
return User::findOrFail($id);
}
这样做的缺点是模型很快就会变得庞大。
那么,这里的最佳实践是什么?
【问题讨论】:
-
有一个类似 MVC 的口头禅,你应该瞄准“瘦控制器,胖模型”——所以如果你的数据库逻辑在模型中,那是一件好事。 ORM 调用在控制器中是可以的,但我认为 Laravel(正确)建议将业务逻辑放在控制器之外,以便更容易测试(我认为这在 Laravel-land 中被称为命令)。
-
@halfer 所以你是说有第四层?控制器处理请求,命令处理业务逻辑,模型处理数据(基础),视图处理表示?
-
是的,这是一个很好的表达方式。当人们开始在 Web 应用程序中使用 MVC-ish 模式时,大部分逻辑将进入控制器类,这在单元测试时通常很难解耦。当然,第一个解决方案是确保任何特定功能都有自己的类(例如,导出屏幕可能使用可重用的
Export类),但有时在命令之外的命令中有一个“胶水”层很不错控制器。这可能会返回成功/失败布尔值,也可能会返回任何 UI 消息供控制器传递给视图。 -
(我不了解 Laravel,但这是我通过阅读有关它的一些内容以及亲身经历将过多的业务逻辑填充到 PHP MVC 控制器中相关的问题的理解)。
-
粘合层(或命令)也将接受来自控制器的用户输入。一个很好的测试你是否有一个好的粘合层是:“你能轻松切换到 Symfony/Zend/Cake/Slim 吗?”