最好的选择是使用 #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() 之类的东西 - 尽管我得出的结论是,在结构正确的应用程序中,GETandPOSTparameters 应该不共享同名。
您在代码 sn-p 中看到的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 应用程序不同的响应。