简短的回答是:是的 PHP 可以。
(注意,它并不完全是原始论文中描述的 MVP,而是 Web 的变体)
MVC 和 MVP 的区别在于,视图是完全被动的,不知道模型层。在 MVC 中,它不是被动的并且知道模型层。在正确的 MVP 中,View 类(如果是)也不应该实现构造函数。
MVP 的典型示例将由以下部分组成:
- 数据访问层(DataMappers、ORM 等)
- 业务逻辑(如验证和计算)
- 被动视图类(可以是模板,但最好坚持使用类)
- 连接模型和视图的演示者
一个例子,说明如何使用 PHP 实现 Model-View-Presenter
注意:现实场景中的模型不是类,而是抽象层,其中包含很多类来处理应用程序逻辑。出于演示目的,我将其称为“模型”。
class Model
{
public function getSomeStuff()
{
return array('foo' => 'bar');
}
}
class View
{
public function render($path, array $vars = array())
{
ob_start();
extract($vars);
require($path);
return ob_get_clean();
}
}
class Presenter
{
private $model;
private $view;
public function __construct(Model $model, View $view)
{
$this->model = $model;
$this->view = $view;
}
public function indexAction()
{
$data = $this->model->getSomeStuff();
// Variables are set now, render the HTML
// And returns as a string
return $this->view->render('path/to/template.phtml', $data);
}
}
文件:template.phtml
<!DOCTYPE html>
<html>
<head>
<title>...</title>
</head>
<body>
<?php foreach($vars as $key => $value): ?>
<p><?php echo $key; ?> : <?php echo $value; ?></p>
<?php endforeach; ?>
</body>
</html>
而用法是:
$model = new Model();
$view = new View();
$presenter = new Presenter($service, $view);
echo $presenter->indexAction();
请注意,这是一个非常简化的示例。在实际场景中,任何基于 MVP 的应用程序应该还实现以下功能:路由器、SPL 类自动加载器。