iba*_*ore 2 php model-view-controller
在 MVC 应用程序中,很容易理解控制器如何从请求中提取数据并更新模型层,但我有点困惑,当视图不知道时视图应该如何从模型层检索数据要求?
例如,如果我去
http://www.site.com/product/view/428
Run Code Online (Sandbox Code Playgroud)
我路由 URL 并分派请求,最终到达控制器。控制器中不需要执行任何操作(我认为?),当它到达我的视图时,我需要产品 ID,但视图不应该从请求中提取数据,所以我该怎么办?
谢谢。
有两种方法可以处理这个问题,这两种方法实际上都表明控制器在这种情况下发挥着重要作用。
解决此问题的第一个选择是尽可能遵循经典 MVC 。这有点与人们所说的“你不能为 Web 做经典的 MVC”的意思有关。在经典 MVC中,视图观察模型层。这部分实际上是可以实现的。
如果这是您想要采用的方法,那么您将必须了解观察者(1) , (2)模式以及如何在 PHP (1) , (2)中使用它。尽管有人在推动摆脱观察者模式。
由于我没有以任何有意义的方式探索这种方法,因此我不会给出任何例子。
如果您阅读 Fowler 的 “GUI 架构”文章,您可能会注意到其中指出视图和控制器形成对的部分。当将 MVC 的思想应用于 Web 环境时,有多种方法可以在应用程序的引导阶段从中受益。
仅供参考:我不再那么确定您可以将这种方式称为“Model2 MVC”。存在一些重大的不一致之处。当我无聊的时候,我会进一步探讨这个令人烦恼的怀疑。
考虑这个片段:
$router->route( $request );
$resource = $request->getParameter('controller');
$view = new {'Views\\'.$resource}($serviceFactory);
$controller = new {'Controller\\'$resource}($serviceFactory, $view);
$method = $request->getMethod(); //post, get & etc.
$command = $request->getParameter('action');
$controller->{$command.$method}($request);
$view->{$command}();
echo $view->render();
Run Code Online (Sandbox Code Playgroud)
示例 URL 中的控制器片段为,操作"product"将包含。我留下了这些名称而不是资源/命令对,以使其不那么混乱。"list"
如果您一开始的前提是视图和控制器在某种程度上是配对的(配对是否具有内聚性是有争议的),那么您可以使用相同的名称来表达它。这还允许您将视图的初始化移出控制器。
上面片段中封装的另一个方面是,由于 Web 的请求响应性质,控制器中的每个操作都需要视图中的伴随操作。与在控制器中执行操作的方式类似,您也可以选择在视图中调用特定的、与路由相关的方法。这将从视图中删除一些样板条件,让您更好地组织整个事情(这有点“高度主观的位”)。
那么..如何将/product/view/428请求转化为网站上可见的内容?
您可能知道,控制器的职责是更改模型层的状态,在本例中可能会编写如下代码:
public function getView( $request )
{
$warehouse = $this->serviceFactory->provide('warehouse');
$warehouse->chooseItem( $request->getParameter('id') );
}
Run Code Online (Sandbox Code Playgroud)
您的视图实例使用模型层的启动服务来获取数据:
public function view()
{
$warehouse = $this->serviceFactory->provide('warehouse');
..
..
// retrieve data about sales for product with ID: 428
$something = $warehouse->getSalesFigures();
..
}
Run Code Online (Sandbox Code Playgroud)
视图的具体实现将取决于您愿意深入的程度。两个最合理的选择是:
my 2 cents