我是MVC的新手。你被警告了......
我有User模型可以将MySQL结果资源返回给控制器。控制器将MySQL资源传递给要显示的视图。是否可以使用数据库结果提取功能在视图中打印查询结果?
<?php while($row = some_fetching_function($database_result_resource): ?>
<tr>
<td><?=$row['Username']?></td>
...etc
</tr>
<?php endwhile; ?>
这对我来说不合适。它是紧密耦合的,对吧?模型必须返回某种类型的数据库资源,并且视图必须使用某种类型的数据库提取方法来遍历它。可以解耦而不会在结果中循环两次吗?我想你必须遍历模型中的结果来创建结果数组,然后再次在视图中。
总结:
答案 0 :(得分:6)
如果你抽象出代码的数据库部分,我认为这是可以接受的。例如,您可以提供可以迭代的“行集”(实现Iterable接口或其他东西)。在幕后,此对象可以包含数据库结果并使用提取功能。
基本上这个想法是你的视图处理一个通用的行集,并不意味着它来自数据库或任何其他来源,这样你就减少了耦合。
答案 1 :(得分:2)
当然可以。但实际上你不应该在视图中获取行。在控制器中进行模型数据的分配,但不能直接在视图中进行。正如Hooray Im Helping指出的那样,获取数据取决于您使用的模型。但是,您的视图中不应该有任何特定于数据库的方法或模型逻辑。如果model实现了通用Iterator接口,则可以将其直接传递给视图。
<?php
public function someControllerAction($params)
{
$myModel = Model::getModel('Model Name');
// But you don't do Model::getModel('Model Name')->getResults($params['date']) in your viewa
$this->view->rows = $myModel->getResults($params['date']);
}
?>
答案 2 :(得分:0)
正如Jani所说,您应该将MySQL结果包装在一个实现标准PHP库中的Iterable接口的类中。通过这种方式,您的视图可以使用熟悉且通用的foreach构造,而不必对结果进行两次迭代,只需将其放入数组中即可。
class rswrap implements Iterator { var $rs; var $current; function __construct($rs) { $this->rs = $rs; } function rewind() { // do nothing } function next() { $this->current = some_fetching_function($this->rs); } function current() { return $this->current; } function valid() { return $this->current !== false; } function key() { return 0; // usually sufficient but you may want to write a real key function. } } $resultset = new rswrap($database_result_resource); foreach($resultset as $row) { // your code here }
答案 3 :(得分:0)
我认为最好的方法是将SQL查询的结果抽象为对象列表并返回列表。
我不认为迭代行集将视图与您正在使用的特定数据库连接分离。视图应独立于正在使用的数据库连接。如果您决定使用JDBC或hibernate,或者任何过渡都不需要修改视图。