Php 模型-视图-控制器新透视图
大家早上好。最近我读了一篇关于mvc模式的文章,文章中说大多数php框架都错误地实现了mvc模式。 在阅读了这篇文章并回顾了它的实现之后,出现了一个问题。 究竟如何在视图中调用模型中调用的方法?我想说的是。 这是本文中的一段代码Php 模型-视图-控制器新透视图,php,Php,大家早上好。最近我读了一篇关于mvc模式的文章,文章中说大多数php框架都错误地实现了mvc模式。 在阅读了这篇文章并回顾了它的实现之后,出现了一个问题。 究竟如何在视图中调用模型中调用的方法?我想说的是。 这是本文中的一段代码 <?php $model = $_GET['model']; $view = $_GET['view']; $controller = $_GET['controller']; $action = $_GET['action']; if (!(empty($mo
<?php
$model = $_GET['model'];
$view = $_GET['view'];
$controller = $_GET['controller'];
$action = $_GET['action'];
if (!(empty($model) || empty($view) || empty($controller) || empty($action))) {
$m = new $model();
$c = new $controller($m, $action);
$v = new $view($m);
echo $v->output();
}
控制器和模型部分之间没有1:1的相关性(注意:不是“模型”,而是模型部分)。仅仅因为你有一个“索引控制器”,并不意味着你需要一个“索引模型”和“索引视图”
M、V和C不是一起构造的。控制器被构造,然后它决定加载/构造/调用哪个模型方法,以及哪个视图应该响应请求。
关于控制器是否应该调用视图,或者模型是否应该“更新”视图,存在一些讨论。由于web请求是短暂的,并且没有“常量”视图,因此后者在PHP中没有什么意义;它更适合原始SmallTalk或Obj-C或类似环境
第一个代码段糟糕地使用了empty
(请参阅),并且不应该将所有部分一起构造
MVC应采用如下方式:
- 应用程序中的模型是。它不仅仅是一个“数据处理程序”或“数据存储”,它是核心应用程序。就业务逻辑而言,应用程序所做的一切都是“模型”。这包括发送电子邮件通知、数据库维护工作和诸如此类的辅助工作,它们都在模型中
- 视图负责生成各种形式的输出。视图应该能够与模型交互,以获取完成其工作所需的数据。数据不应该被“推入”视图,视图应该能够“拉”出它所需要的数据;否则,视图外部的东西需要知道视图需要什么数据,这意味着视图逻辑不再是视图中的自包含逻辑
- 控制器只是剩下的一点点胶水,用来调用正确的模型方法和视图以响应传入的请求
我通常会这样构造这些部分:
- 该模型由多个部分组成,包括数据存储处理程序、“原语”(为单个业务对象建模的类)和“服务”。“服务”包含应用程序可以执行的所有“操作”,并形成模型API。每当你想在应用程序中“注册用户”或“获取日期范围X到Y的所有记录”时,服务API中都有一种专门的方法。只要看看这个服务API,你就应该能够列举你的应用程序“做”的所有事情
- 有一个对象是“dispatcher”或“service locator”,或者只是一个依赖项注入容器,它简化了这些服务类的实例化并允许有人调用它们。控制器获取其中一个,视图也获取其中一个
- 有一个路由器,它根据URL执行一些“粗略路由”,调用一个控制器方法。控制器进一步查看请求的细节,并决定调用模型方法和/或使用视图进行响应
- 视图可能会根据请求的具体情况决定显示某些数据的最佳方式,例如,是使用HTML页面还是JSON数据blob进行响应。对RESTful服务很满意
在粗略的伪代码中:
$r = new Router;
$r->route($_GET, $_POST, $_SERVER); // or something like that
这将发送到以下对象:
class FooController {
public function __construct(ServiceLocator $services) { ... }
public function bar(Request $request) {
$request->assertIsPost();
$this->services->locate('Baz')->froogleTheWibbles($request->getPostParams());
(new BarView($this->services))->displayWibbles($request);
}
}
class BarView {
public function __construct(ServiceLocator $services) { ... }
public function displayWibbles(Request $request) {
switch ($request->accepts()) {
case 'html' :
$this->loadTemplate(...);
...
case 'json' :
echo json_encode($this->services->locate('Baz')->getWibbles());
}
}
}
模型会做它需要做的一切
class Baz {
public function froogleTheWibbles(array $data) {
foreach ($data as $wibbleData) {
$wibble = new Wibble($wibbleData);
$this->wibbleStore->save($wibble);
}
...
}
}
MVC没有“一个答案”,重要的是模型包含了你的应用程序“做”的一切,独立于输入和输出,视图可以根据要求尽可能独立地生成正确的输出,控制器只是处理输入条件的一点点胶水。实现这一点的方式多种多样。重要的设计原则应该是实现视图和控制器可以互换以适应不同的条件(网页、JSON API、XML API、SOAP API、CLI调用、ZeroMQ节点等),但“模型”不是
控制器和模型部分之间没有1:1的相关性(注意:不是“模型”,而是模型部分)。仅仅因为你有一个“索引控制器”,并不意味着你需要一个“索引模型”和“索引视图”
M、V和C不是一起构造的。控制器被构造,然后它决定加载/构造/调用哪个模型方法,以及哪个视图应该响应请求。
关于控制器是否应该调用视图,或者模型是否应该“更新”视图,存在一些讨论。由于web请求是短暂的,并且没有“常量”视图,因此后者在PHP中没有什么意义;它更适合原始SmallTalk或Obj-C或类似环境
第一个代码段糟糕地使用了empty
(请参阅),并且不应该将所有部分一起构造
MVC应采用如下方式:
- 应用程序中的模型是。它不仅仅是一个“数据处理程序”或“数据存储”,它是核心应用程序。就业务逻辑而言,应用程序所做的一切都是“模型”。这包括发送电子邮件通知、数据库维护工作和诸如此类的辅助工作,它们都在模型中
- 视图负责生成各种形式的输出。视图应该能够与模型交互,以获取完成其工作所需的数据。数据不应该被“推入”视图,视图应该能够“拉”出它所需要的数据;否则,视图外部的东西需要知道视图需要什么数据,这意味着视图逻辑不再是视图中的自包含逻辑
- 控制器只是剩下的一点点胶水,用来调用正确的模型方法和视图以响应传入的请求
我典型的结构
class Baz {
public function froogleTheWibbles(array $data) {
foreach ($data as $wibbleData) {
$wibble = new Wibble($wibbleData);
$this->wibbleStore->save($wibble);
}
...
}
}