代码之家  ›  专栏  ›  技术社区  ›  joedevon

在Zend Framework中,在视图中设置变量还是在控制器中设置变量更好?

  •  2
  • joedevon  · 技术社区  · 17 年前

    Eric Clemmons

    编辑

    详细.phtml:

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

    7 回复  |  直到 15 年前
        1
  •  5
  •   Bill Karwin    17 年前

        2
  •  2
  •   Alana Storm    17 年前

    View Helpers 通过封装对模型“获取数据”方法的调用来返回信息。这会让你远离 Passive View 许多其他PHPMVC框架所采用的模式。视图将直接传递到模型以获取数据。您担心的是,多次调用视图帮助程序将导致模型两次获取数据。这是一个似乎很容易避免的潜在性能问题。

    //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];
    }
    

    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>
    

    它仍然有点笨拙,但你的视图文件(顶部只有一行)的一致性会减少气味。也就是说,缓存是实现这一点的“正确”方式。避免这种情况只是用一种气味换另一种气味。当你定义一个视图变量时(直接在视图中或通过在控制器中设置它),你已经在使用缓存,只是以一种随意的方式。

        3
  •  2
  •   Lance Rushing    17 年前

    简短的回答:依我之见,是的,把它放在控制器里。

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

        4
  •  2
  •   Pascal MARTIN    17 年前

    另一方面,我喜欢这种缓存的想法。..事件,如果你认为它太复杂/矫枉过正。


    您可以为此使用静态变量;要么在你的课堂上,要么直接在方法中

    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)
    

    这难道没有帮助吗?我猜,在你的情况下 A 类是视图助手,顺便说一句;-)A和 mt_rand


    Zend_Memory 而不是静态变量:如果我没记错的话,它处理的是占用的RAM量(例如,如果需要,它可以从“缓存”中删除数据)。

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

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

        5
  •  1
  •   Svetoslav Marinov    17 年前

    $这个->视图->some变量=1;

    ....

        6
  •  1
  •   Justin    17 年前

        7
  •  1
  •   lo_fye    17 年前

    因此,我开始在detail.html中使用几行php来设置变量。

    视图可以包含任意多的显示逻辑。

    在我自己的工作中,我倾向于在控制器中分配所有变量,除非我使用视图助手来呈现导航、广告等。视图助手实际上是用于您将在网站的许多部分重复使用的东西。

    当将控制器中的变量分配给视图时,如果我有一个记录集,我倾向于遍历该记录集并将它们推送到关联数组中。我没有将实际的记录集传递给视图,而是将这个数组传递给它。

    这样做的原因是,我可以:

    1. 在控制器中执行任何连接或其他提取操作
    2. 将琐碎的显示逻辑排除在视图之外(即为偶数行和奇数行设置css类等)

    控制器示例:

    $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;?>