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