Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在视图中设置变量还是在Zend框架中设置控制器更好?_Php_Model View Controller_Zend Framework_View Helpers - Fatal编程技术网

Php 在视图中设置变量还是在Zend框架中设置控制器更好?

Php 在视图中设置变量还是在Zend框架中设置控制器更好?,php,model-view-controller,zend-framework,view-helpers,Php,Model View Controller,Zend Framework,View Helpers,我的问题需要一点设置,请耐心听我说: 我变成了一个使用视图助手从模型中获取数据的人,而不是把数据洒在控制器上(帽子尖到)。它的可重用性和灵活性更高。我就是喜欢 我通常做的是在index.phtml中布置模板,然后当我需要从模型中获取一些东西时,将该片段放入detail.phtml中,这样逻辑就尽可能地不受影响了 然而,我开始看到需要重用变量。例如,类别名称。现在,您不希望使用视图辅助对象一次又一次地从模型中获取cat名称。虽然你可以缓存它,但这显然是一个很大的麻烦 因此,我开始在detail.p

我的问题需要一点设置,请耐心听我说:

我变成了一个使用视图助手从模型中获取数据的人,而不是把数据洒在控制器上(帽子尖到)。它的可重用性和灵活性更高。我就是喜欢

我通常做的是在index.phtml中布置模板,然后当我需要从模型中获取一些东西时,将该片段放入detail.phtml中,这样逻辑就尽可能地不受影响了

然而,我开始看到需要重用变量。例如,类别名称。现在,您不希望使用视图辅助对象一次又一次地从模型中获取cat名称。虽然你可以缓存它,但这显然是一个很大的麻烦

因此,我开始在detail.phtml中使用几行php来设置变量。而且闻起来也不对劲了。视图不应该有太多的逻辑

你们大家怎么说?如果var被重用,是否将其放在控制器中?或者不介意在视野中设置几个VAR

编辑:Alan Storm询问查看帮助程序的示例:

detail.phtml:

<ul id="productList">

<? foreach($this->getProductById($id) as $product) : ?>
    <li><?= $this->escape($product['name']) ?></li>
<? endforeach; ?>

</ul>
(准备迎接反短贴者的攻击)

另一次编辑
我知道不可能有两个正确答案。哦,好吧…

控制器和视图都不是用来存储应用程序状态的。这就是这个模型的用途


请记住,MVC中的“模型”不是数据库表!模型是实现应用程序业务逻辑的地方,将其存储在数据库中是模型的内部实现细节。但是你的应用程序中可以有与数据库无关的模型。

简短回答:嗯,是的,把它放在控制器中

原因:

1) 将变量传递到视图中的控制器是更典型的MVC


2) 可维护性:当我在3个月后再次访问视图时,我不想在相邻的视图/模板中查找变量。现在您又回到了意大利面代码,必须猜测特定变量的来源。

我真的不喜欢这种变量的想法:它在视图或控制器中添加了更多代码,感觉不太好

另一方面,我喜欢缓存的想法。。。如果您认为它太复杂/过火,则会发生此事件

为什么在中间找不到路?不使用像file/APC/memcache这样的缓存,而是将数据保存在内存中以执行脚本?
你可以使用一个静态变量;要么在类中,要么直接在方法中(取决于“在类的方法之间共享该缓存有意义吗?”)

为了说明这个想法,下面是代码的一部分;考虑这个类:

class A {
    public function test($param) {
        static $cache = array();
        if (isset($cache[$param])) {
            var_dump("cache hit : $param = {$cache[$param]}");
            return $cache[$param];
        } else {
            // Fetch from DB (here, simulated ^^ )
            $cache[$param] = mt_rand(0, 9999);
            var_dump("cache miss : $param = $cache[$param]");
            return $cache[$param];
        }
    }
}
test
方法使用一个静态变量(该变量将有一个且只有一个实例由类的任何实例共享)来存储从数据库中获取的数据

如果你这么说:

$a = new A();
$b = new A();

$a->test(10);   // miss
$a->test(15);   // miss
$b->test(10);   // hit
$b->test(25);   // miss
$a->test(25);   // hit
您将得到以下结果:

string 'cache miss : 10 = 3745' (length=22)
string 'cache miss : 15 = 7800' (length=22)
string 'cache hit : 10 = 3745' (length=21)
string 'cache miss : 25 = 8623' (length=22)
string 'cache hit : 25 = 8623' (length=21)
每次使用新参数调用该方法时,都是未命中,然后转到DB。但是,当一个参数已经使用过一次时调用它时,数据就在内存中,而您不需要转到DB;-)

那不会有帮助吗?我猜,在你的例子中,
A
类是视图助手,顺便说一句;-)而
mt_rand
将是一个DB查询^^

作为旁注:这不应该做太大的对象,因为它将使用一些RAM。。。而且没有太多的这些


编辑:当您使用Zend Framework时,您可能会对使用而不是静态变量感兴趣:它处理诸如占用的RAM量之类的事情(例如,如果需要,它可以从“缓存”中删除数据),如果我没记错的话

另外:是的,您仍然多次调用该方法。。。但这总比查询好。。。这样,视图和控制器都不必关心任何类型的“缓存”:这不是他们的工作


而且:我多年来一直在使用这种技术,没有任何问题(只要我只以这种方式存储小对象,而不是太多);我不是唯一一个用这个的人;例如,Drupal也使用这种技术。

我不确定您所说的确切技术。下面假设您正在通过包装对模型的“get data”方法的调用来创建返回信息的方法。这使您摆脱了许多其他PHP MVC框架所采用的模式。视图将直接转到模型以获取其数据。您的问题是对视图助手的多次调用将导致模型两次获取数据。这是一个似乎很容易避免的潜在性能问题

//example of how I'm assuming you're using view helpers
echo $this->viewHelperName->modelName->getDataIWant('key');
如果这准确地描述了您的问题,那么“如果我需要使用它两次,请在控制器中设置一个视图变量,否则只使用视图辅助对象”的方法可能是错误的。这是我个人的偏好,但无论您选择哪种方法从模型获取数据到视图,您都应该在整个应用程序中坚持使用

您试图解决的问题是“直接从模型中获取数据会带来高性能成本”。这是模型实现应该解决的问题。这不是janky编码风格应该解决的问题:)

正如您已经提到的,最好的解决方案是缓存。如果你聪明的话,缓存不必“太麻烦”

public function getDataIWant($key, $clear_cache=false)
{
    if(!array_key_exists($key, $this->_cache) || $clear_cache)
    {
        $this->_cache[$key] = parent::getDataIWant[$key];
    }

    return $this->_cache[$key];
}
如果缓存对于您使用模型的方式不可行,那么我建议在您的模型中添加一个方法来获取所需的数据,并使用extract在视图范围中定义变量

class MyModel
{
    ...
    function getDataForFooView
    {
        return Array(
            'company_name'=>$this->getCompanyName
        );
    }
    ...
}

...
//top of the view file
<?php extract($this->viewHelper->modelName->getDataForFooView()) ?>
<h1><?php echo $company_name; ?></h1>
classmymodel
{
...
函数getDataForFooView
{
返回数组(
“公司名称”=>$this->getCompanyName
);
}
...
}
...
//顶视图文件
$count = 0;
$list = array();
$result = mysql_query("select * from items limit 10");
while($item = mysql_fetch_object($result))
{
   if($count % 2 ==0){ $css_class = 'even'; } else { $css_class = 'odd'; }
   $count++;
   $item->css_class = $css_class;

   if($item->first_name && $item->last_name)
   {
      $item->name = $item->first_name.' '.$item->last_name;
   }
   else
   {
      $item->name = $item->username;
   }

   $list[] = $item;
}
$this->view->list = $list;
<?foreach($this->list as $item):?>
<tr class="<?=$item->css_class?>">
    <td><?=$this->escape($item->name)?></td>
</tr>
<?endforeach;?>