当我有一个控制器,例如文章我经常有action_view()
来处理大部分代码。
有时,它可以变成80-100行。
我的控制器通常处理所有这些:
我可以看到我可以在控制器中创建另一个私有方法的位和碎片,不一定是为了重用,而是为了分离关注点。
然而,对我来说,看起来很奇怪(对我来说)有可以通过路径调用的方法,以及只有内部的方法。
还有一些事情对我说“我应该在模特中,而不是控制者”。但是,我不确定这是否正确。
最后,我有一个有点胖的控制器方法看起来非常程序化。
我是否真的应该在action_*
方法之上列出一个列表,然后将其余的代码分成更小的模块?
我在下面有一个例子......这是典型的控制器内容,还是会话等应该在模型中?
public function action_pdf($type, $id) {
// Get PDF file from db and send headers to it
$id = (int) $id;
$pdfFile = $this->model->getPdf($id, $type);
if ($pdfFile) {
$this->request->redirect($pdfFile);
} else {
$this->session->set('pdfMissing', true);
$this->request->redirect(Route::get('properties')->uri());
}
}
所以,我的问题是,我做错了吗?
答案 0 :(得分:3)
您的模型用于封装业务逻辑,通常用于抽象数据存储层远离架构的其余部分(控制器,视图)。
这意味着任何数据库访问(例如SQL查询)等都应该理想地包含在模型中。您的控制器将从您的模型中获取其数据(这包括ORM,它通过模型公开自己),而无需直接访问数据库。
就电子邮件发送而言,我猜这取决于具体情况。例如,当用户注册时,我调用Model方法将其详细信息插入数据库。然后,此方法会触发将电子邮件发送给他们。这样我就可以让电子邮件发送注册业务逻辑的明确部分(这就是我想要的),所以无论谁在模型中调用注册方法,系统都不会忘记发送电子邮件。
在表单验证方面,我尝试在ORM模型类中指定大部分验证规则。这样无论是谁操纵模型,模型总是对如何验证自己的数据有一些内在的理解。您会注意到ORM模型对象已经提供了验证其数据的方法。模型本身不需要知道的任何额外验证/回调可以在模型代码之外完成。
答案 1 :(得分:1)
IANAPHPD(我不是PHP Dev)但是通用编程语言(Java / C#)开发人员的观点可能会有所帮助。对我来说,MVC的一个好处是,当您拥有需要呈现多个UI的核心业务逻辑和基础架构时,可以促进代码重用。例如,具有Web界面和桌面界面的订单管理系统。在这种情况下,核心逻辑是模型。三个接口中的每一个都有自己的视图和控制器。在C#中,构造代码非常简单,以便核心逻辑位于从桌面UI项目和Web应用程序项目引用的一组包/程序集中。
我认为即使我非常确定某个特定应用不需要其他用户界面,也会按照这些条款。当我试图决定是否应该在模型或控制器中进行某些操作时,我问自己该功能是否应该可以从其他UI重用。
这是一种有点不自然的思考PHP代码的方式,因为PHP与Web平台紧密相关(据我所知)。无论如何,这种思维方式仍然适用(关注点分离并且不要重复自己)仍然可以应用: PHP可以支持的辅助“UI”将是一个Web服务API 。如果某个功能应该可用于网站和Web服务API,那么它应该在模型中公开。
您可能有兴趣或可能不感兴趣,但总的来说,这种思维方式与领域驱动设计完美融合。
注意:虽然PHP支持的所有UI都是基于网络的,但我仍然要小心将特定于Web的问题放入模型中(与浏览器会话,cookie,命中跟踪等相关的任何内容),主要是因为那些关注点是以表示为中心而不是以业务为中心,其次是因为这使得以后出于某种原因将系统零碎地移植到另一种语言/平台更加困难。