我的PHP系统中存在常见的MVC情况:Controller
收到来自包含View
数据的$_POST
的请求。现在我有三种方法来处理数据:
a)Controller
仅调用Model
,Model
调用$_POST
数据。
b)Controller
将$_POST
数据转换为变量并将其传递给Model
。
c)Controller
将$_POST
数据转换为Model
的域对象,并仅将对象传递给Model
。
目前,我正在关注选项A,但我认为这是错误的,所以我在考虑使用选项C.
那么,根据MVC,处理$_POST
数据的正确方法是什么?
编辑目前,我没有使用任何MVC框架。
编辑2 通常,相同的Controller
处理来自浏览器,网络服务,离线应用程序等的请求,或者每个人拥有它Controller
?< / p>
答案 0 :(得分:26)
最佳选择是使用#2 方法,并进行一些更改 我会把它写成这样的东西:
public function postLogin( $request )
{
$service = $this->serviceFactory->build('Recognition');
$service->authenticate( $request->getParam('username'),
$request->getParam('password') );
}
// Yes, that's the whole method
如果您使用类似Request
实例的内容来抽象用户的输入,则无需实际创建变量。
此外,您可能希望将
Request::getParam()
方法替换为类似Request::getPost()
的方法 - 尽管我得出的结论是,在结构正确的应用程序中,GET
和POST
参数不应共享相同的名称。
您在代码段中看到的serviceFactory
将是您在控制器和视图实例中注入的对象。它允许您在控制器和视图之间共享相同的服务实例。
它负责创建services (其中包含应用程序逻辑,同时将域业务逻辑保留在domain objects),这有助于您隔离交互领域实体和表示层的存储抽象之间。
Controller仅调用Model,Model处理$ _POST数据。
在MVC和MVC启发的设计模式中,模型应该既不了解用户界面也不了解整个表示层。 PHP中的$_POST
变量是superglobal。
如果将它与模型层一起使用,您的代码将绑定到Web界面甚至特定的请求方法。
Controller将$ _POST数据转换为Model的对象,并仅将对象传递给Model
不完全确定你的意思。似乎你在谈论抽象的实例化,它包含用户的请求。但在这种情况下,控制器负责实例化/创建所述结构,这将违反SRP。
您必须了解的一点是,在基于Web的MVC应用程序的上下文中,应用程序的 User 是浏览器。不是你。浏览器发送请求,由路由机制处理并由控制器传播。并且视图会将响应生成到您的浏览器。
另一件事是:模型既不是类也不是对象。 Model is a layer。
通常,同一个Controller处理来自浏览器,Web服务,离线应用程序等的请求,或者每个控制器都拥有自己的Controller?
您应该能够使用单个控制器来处理所有形式的应用程序。但这只是条件,你实际上是在所有3个用例中使用相同的应用程序。
为此,有两个条件:
Request
实例,该控制器接收这样您就可以拥有一个应用程序来满足所有要求。唯一的,每个变体都有不同的是引导阶段,您可以在其中创建Request
实例并选择正确的视图。
在您描述的情况下,更改部分实际上是视图,因为预期REST或SOAP服务会产生与普通Web应用程序不同的响应。
答案 1 :(得分:3)
曾几何时是三层应用程序架构。
这一切都取决于你的MVC框架。通常,Controller执行用户和模型层之间的链接,模型层操纵域对象。
在PHP的MVC早期,模型层实际上只是域对象,为此目的称为模型。 有些人倾向于使用所谓的瘦模型,它只提供数据的OO表示(这简化了持久性)。在这种情况下,控制器将重新组合所谓的动作,包含与HTTP请求(胖控制器)相关的大部分处理。
其他人使用专用方法(胖模型)在对象模型中嵌入大部分所述处理。
但是,在某些时候,您必须分析查询的内容以进行清理和验证,这取决于您的视图将如何格式化请求。清理可能是一个控制器任务(此请求应该只包含这些值),而验证绝对是一个模型任务(值应该是这些类型)。
一个有趣的问题是:您如何处理影响多个域对象的操作?你把它的逻辑放在哪里?
如今,模型层由将域对象与控制器的邪恶把握隔离开来的服务组成,以限制层之间的依赖关系到它们各自的接口。这是大多数请求处理完成的地方。
例如,Symfony2为这个问题提供了一个明智的答案:处理请求的每个步骤都是在一段专用代码中实现的,可以描述如下:
然后分几个步骤打破服务工作:
CakePHP是另一个流行的框架,遵循类似的概念:简单的控制器和封装域对象的服务。
请参阅this question以更好地了解一般概念。
有关其他答案,请参阅this other question。
感谢tereško对此事的宝贵意见。
答案 2 :(得分:1)
我正在使用Zend并关注
第二个选项。
注册表单示例
step-1 表单将post值发送给指定的控制器
步骤-2 我将通过服务器端验证验证表单值(邮件和网址以及空帖子值)。
步骤-3 将已检查的帖子数据以变量或整数发送给模型。
第4步 - 控制器调用模型。
步骤 -5模型会插入帖子值并创建新用户。
我认为无论您使用哪种框架或认可,您的第二种选择都会更好。
注意 - 同一个控制器可以处理everthing取决于您的应用程序逻辑。
but i prefer to keep different controller for differnt user request and user types
it helps in keeping code readable managebale .
答案 3 :(得分:0)
查看一些MVC框架。
例如,在Yii中,您可以在操作:
中编写此类代码$model = new Model();
if(isset($_POST['Model'])) {
$model->attributes = $_POST['Model'];
}
请注意,必须通过验证规则传递模型的所有attributes
。在Yii中,验证适用于(实际上,之前)$model->save()
见:
答案 4 :(得分:0)
'C'是最佳选择。你不应该让原始的$ POST数据进入模型,因为模型应该是通用的处理存储和加载操作。
示例:相同的模型可以使用Web界面和Web服务。在Web $ _POST是有效的,但对于Web服务,它不是。所以模型并不关心如何接收数据,而只关心如何存储和加载数据。
Yii绝对是MVC的干净实现。