【发布时间】:2010-09-30 17:45:25
【问题描述】:
PHP 程序如何在模型、视图和控制器页面之间传递值?例如,如果控制器有一个数组,它如何将它传递给视图?
编辑:
感谢您的回答。我看到其中有几个声明组件在同一个页面中,但是当我查看 CodeIgniter 之类的东西时,我看到了模型、视图和控制器的三个单独的 PHP 页面。
【问题讨论】:
PHP 程序如何在模型、视图和控制器页面之间传递值?例如,如果控制器有一个数组,它如何将它传递给视图?
编辑:
感谢您的回答。我看到其中有几个声明组件在同一个页面中,但是当我查看 CodeIgniter 之类的东西时,我看到了模型、视图和控制器的三个单独的 PHP 页面。
【问题讨论】:
通常您的控制器将创建一个视图对象,并在创建该视图对象时传递信息。
<?php
class Controller {
public function __construct() {
$arr = array("a","b","c");
$myView = new View($arr);
}
}
class View {
private $content;
public function __construct($content) {
$this->content = $content;
include_once('myPage.inc.html');
}
}
?>
【讨论】:
CodeIgniter 与大多数 PHP MVC 框架一样,带有一个视图“引擎”。换句话说,框架中有一个类负责将数据从控制器加载和传输到视图。
特定于 CodeIgniter,这些调用如下所示:
$data = array(
'title' => 'My Title',
'heading' => 'My Heading',
'message' => 'My Message'
);
$this->load->view('blogview', $data);
您的视图将是一个单独的 php 页面,在本例中为 blogview.php。它可能看起来像这样:
<html>
<head><title><?= $title ?></title></head>
<body>
<h2><?= $heading ?></h2>
<p><?= $message ?></p>
</body>
</html>
负责在控制器和视图之间传输数据的部分是 CodeIgniter 内部的视图引擎(或类)。它从控制器中获取该数组并将其反序列化以用于视图。
那么为什么是两个单独的文件呢? MVC 范式是这样的,在设计上,您希望您的业务逻辑与您的 UI 分离。如果您对数据库做的不多,则不需要合并 MVC 的模型部分。但是当您想进一步将代码的数据访问部分与业务逻辑(为用户操作数据的东西)分开时,它就在那里。在这种情况下,您有 3 个单独的文件;模型、控制器、视图。
所以不,这些组件并不都在同一个页面中,尽管它们当然可以。但是通过使用 MVC 构建程序,您可以干净利落地分离应用程序的操作。这样,您可以一次在一个层中工作,而不会影响其他层。例如,当您找出用户无法登录的原因时,您的 CSS 人员可能会让网站看起来很漂亮。
【讨论】:
extract。这会将数组的键转换为单个变量。见php.net/manual/en/function.extract.php。
我希望约翰尼很久以前就找到了我现在正在寻找的答案,但我可以提供关于如何做到这一点不令人满意的见解!您可以从一个文件(例如收集站点用户输入的数据的“视图”组件)中的一个信息传递到另一个文件(例如检查/验证表单数据并将其发送回表单的“模型”组件用于修订或将其存储在数据库中)。表单值可以通过 POST 或 GET 数组发送,“action”属性确定哪个文件接收数据,例如
<form action = 'form-exec.php' method = 'POST'>
---some set of possible user inputs goes here
<input name='submit' type='submit' value='Go'>
</form>
处理后,您可能希望向表单返回一些数据——例如需要修改的用户输入值或成功消息。您可以将该数据存储在会话变量中,并从“查看”页面上的这些变量中恢复它。那么,如何返回“查看”页面?现在,我在这里是因为我已经看到它使用过并且我自己也使用过它,但是很震惊地读到它,显然,传输是通过一个缓慢的互联网 http 请求进行的——即使传输是到同一个文件中的服务器上的目录!好的,所以返回“视图”组件的不满意方法是几行这样的 PHP 行:
header("location: theinputform.php");
exit;
它确实有效,但肯定有更好的方法吗?我看到有人“咆哮”说您应该只使用包含,但我无法理解如何合理地执行日常操作,即返回页面顶部并根据新条件重新创建它。例如,如果我刚刚登录了一个用户,我这次不想显示登录邀请。包含是有条件地向页面添加内容的简单方法,但我没有找到比上述方法更简单地返回顶部的方法。有没有人对此有任何见解或知识?正如 OP 所述,Johnny 和我想做与 MVC 相同的事情,但没有使用任何类型的 MVC 框架。顺便说一句,有几本书和教程简单地使用了上面的“标题”方法。
好的,编辑:您从表单(即“查看”页面)到使用表单的“操作”属性进行表单处理,如上所述。如果“模型”页面没有输出 html 并且只是“做事”,您可以简单地包含您希望在完成时转到(或返回)的“查看”页面。反正我觉得是!正要试一试……
【讨论】:
我自己也在为这个问题苦苦挣扎。近十年后,我回到了 php 编程。我在将 PHP MVC 框架部署到实验服务器时遇到了几个问题,所以我最终自己构建了一个简单的 MVC 变体。
在我的简单设计(前端)中,控制器与模型交互以填充有效负载对象并将其传递给视图。每个视图都在一个单独的 PHP 文件中实现,因此控制器使用 include 来“加载”所需的视图。 然后视图可以通过有效负载对象的指定名称 ($dataId) 访问数据。
class Controller {
public $model;
...
public function display($viewId,$dataId,$data)
{
$url = $this->getViewURL($viewId);
$this->loadView($url,$dataId,$data);
}
public function getViewURL($key)
{
$url = 'view/list_view.php';
if($key == 'create')
{
$url = 'view/create_view.php';
}
else if($key == 'delete')
{
$url = 'view/delete_view.php';
}
return $url;
}
public function loadView($url,$variable_name, $data)
{
$$variable_name = $data;
include $url;
}
}
【讨论】:
模型、视图和控制器不是单独的页面,而是一页。
所以,不需要“传递”任何东西
【讨论】:
您可以使用smarty 之类的模板引擎将视图与控制器和模型分开。
并使用例如 smarty 的 assign 方法将变量传递给您的模板。
【讨论】: