最好的选择是使用#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
andPOST
参数不应共享相同的名称。
您在代码片段中看到的serviceFactory
将是您在控制器和视图实例中注入的对象。它可以让您在控制器和视图之间共享相同的服务实例。
它负责创建服务 (将包含应用程序逻辑,同时将域业务逻辑留在域对象中),这有助于您将域实体和存储抽象之间的交互与表示层隔离开来。
关于其他选项:
-
控制器只调用模型,模型处理 $_POST 数据。
在 MVC 和受 MVC 启发的设计模式中,模型应该既不了解用户界面,也不了解整个表示层。PHP 中的$_POST
变量是一个超全局的.
如果您将它与模型层一起使用,您的代码将绑定到 Web 界面甚至特定的请求方法。
-
Controller 将 $_POST 数据转换为 Model 的对象,并且只将对象传递给 Model
不完全确定你的意思。似乎您在谈论抽象的实例化,它将包含用户的请求。但在这种情况下,控制器将负责所述结构的实例化/创建,这将违反SRP。
结束语:
您必须了解的一件事是,在基于 Web 的 MVC 应用程序的上下文中,您的应用程序的用户是浏览器。不是你。浏览器发送请求,请求由路由机制处理,由控制器传播。并且视图产生对您的浏览器的响应。
另一件事是:模型既不是类也不是对象。模型是一层。
更新
通常,同一个 Controller 处理来自浏览器、Web 服务、离线应用程序等的请求,还是每个都有自己的 Controller?
您应该能够拥有处理所有形式的应用程序的单个控制器。但这只是在条件下,您实际上对所有 3 个用例都使用相同的应用程序。
要做到这一点,有两个条件:
- 您需要抽象该
Request
控制器接收的实例
- 视图应该在控制器外部实例化
这样您就可以拥有一个应用程序来满足所有要求。唯一不同的是,每个变体都有不同的是引导阶段,您可以在其中创建Request
实例并选择正确的视图。
在您所描述的情况下,更改部分实际上是视图,因为 REST 或 SOAP 服务预计会产生与普通 Web 应用程序不同的响应。