如何在Codeigniter中从View的范围中取消设置变量

时间:2013-10-16 18:00:42

标签: php codeigniter scope codeigniter-2

在我看来,我测试if (isset($winner))。但是,视图在循环中重新打印,我无法将其清除以用于后续测试。

如何实例化新视图或清除/取消设置其控制器给出的变量?

我很欣赏Views有广泛的范围,但这似乎是Codeigniter中的一个错误。

控制器:

for($i=0; $i < 100; $i++) {
    $test = $this->prizedistributor->isWinner();
    echo $this->load->view("simulateResponse", $test, TRUE);
    unset($test['winner']); // this does not work
}     

查看:

<? if (isset($winner)):?>
    WINNER!
<? else: ?>
    LOST!
<? endif; ?>
<?php unset($winner); // this does not work! ?>

结果:

$i==40是唯一的赢家,View会报告所有$ i&gt;尽管Controller总是将布尔值默认为false,但仍为40位获胜者。

更新

我知道测试if(empty($ test))是否允许View正确报告。但是,我的问题是如何取消设置该变量(并从内存中清除它)。这个问题很大程度上源于使用HMVC(模块化codeigniter)时的其他类似问题。但是,在此处发布该代码太复杂,无法说明相同的范围问题。


许多人不断质疑上面不相关的prizedistributor。所以这里有一个更简单的代码示例来说明样本问题

CONTROLLER

function testScope() {
    for($i=0; $i < 10; $i++) {
        if($i == 5)$winner = array('winner' => true);
        else $winner = array();
        echo $this->load->view("testScope", $winner, TRUE);
    }        
}  

查看

<?= (isset($winner))  ? "WINNER!<br>" : "LOST!<br>"; ?>

输出

丢失! 丢失! 丢失! 丢失! 丢失! 优胜者! 优胜者! 优胜者! 优胜者! WINNER!

可能答案:

我查看了codeigniter的system/core/Loader.php并找到了函数_ci_load缓存了第800行的变量。他们的推理是:

  

您可以使用专用的$ this-&gt; load_vars()设置变量   功能或通过此功能的第二个参数。我们将合并   两种类型并缓存它们以便嵌入其他视图   视图可以访问这些变量。

这提出了一个非常好的观点以及我对codeigniter的看法。但问题仍然存在,我们怎么能同时拥有这两个?可能是跳过此捕获的第四个可选参数?

离。 loader->view("testScope", $winner, TRUE, FALSE); ????

6 个答案:

答案 0 :(得分:3)

使用TRUE / FALSE可能比isset更好。

此外,您在发布的代码中加载视图的方式不会向视图发送名为$winner的变量,除非isWinner()返回的内容可能是array('winner' => 'someval')案子。

TRUE/FALSE可能看起来像

for($i=0; $i < 100; $i++) {
    $test = $this->prizedistributor->isWinner();//isWinner() returns either array('winner' => '') or array('winner' => 'somevalue')
    echo $this->load->view("test_view", $winner, TRUE);
}   

视图

<?php if ($winner):?>
    WINNER!<br>
<?php else: ?>
    LOST!<br>
<?php endif; ?>

例如

for($i=0; $i < 100; $i++) {
    if($i == 50){
        $winner = array('winner' => 123);
    }else{
        $winner = array('winner' => '');
    }
    echo $this->load->view("test_view", $winner, TRUE);
}     

打印

...
LOST!
LOST!
LOST!
LOST!
LOST!
LOST!
WINNER!
LOST!
LOST!
LOST!
LOST!
LOST!
LOST!
...

如果您在isWinner()中包含正在发生的事情或者至少提及它返回的内容,那么可能有助于获得更好的答案。

答案 1 :(得分:3)

在Codeigniter 3中,您可以使用方法

$this->load->clear_vars();

See it in documentation

答案 2 :(得分:2)

好的,所以你似乎知道CI缓存传递给视图的变量。变量名称取决于您传递给$this->load->view()的数据的

// $myvar will be cached as "true"
$this->load->view('myview', array('myvar' => true));

// $myvar will still be there
$this->load->view('myview');

// $myvar will still be there, because myvar has not changed
$this->load->view('myview', false);
$this->load->view('myview', array());

要取消设置$ myvar,您必须明确地执行此操作:

$this->load->view('myview', array('myvar' => null));

您的代码:

$test = $this->prizedistributor->isWinner();
echo $this->load->view("simulateResponse", $test, TRUE);

如果$test只是false或null,则不会取消设置或更改已缓存的变量。它实际上什么也没做。你可以使用更像这样的东西:

$test = $this->prizedistributor->isWinner();
echo $this->load->view("simulateResponse", array('winner' => $test), TRUE);

isWinner()返回true / false而不是数组。

不幸的是,我认为您不能真正取消设置变量,但您可以将其设置为null / false。

如果isset($var)

$var === null将返回false。

答案 3 :(得分:1)

您是否尝试直接从视图中获取数据?

控制器

for($i=0; $i < 100; $i++) {
    $this->load->view("simulateResponse");
}    

查看

<? if($this->prizedistributor->isWinner()): ?>
    WINNER!
<? else: ?>
    LOST!
<? endif; ?>

如果您正在寻找MVC解决方案:

控制器

<?php
    for($i=0; $i < 100; $i++)
        $data['winner_array'][$i] = $this->prizedistributor->isWinner();
    $this->load->view("simulateResponse", $data);
?>

查看

<? foreach($winner_array as $win): ?>
    <? if($win): ?>
        WINNER!
    <? else: ?>
        LOST!
<? endif; endforeach; ?>

答案 4 :(得分:1)

您可以创建一个辅助函数来加载视图并在此之后销毁参数。

if (!function_exists('load_cleaned_view'))
{
    function load_cleaned_view($view, $data = NULL, $return_as_string = FALSE)
    {
        $CI =& get_instance();
        $content = $CI->load->view($view, $data, $return_as_string);

        if(!empty($data))
        {
            foreach ($data as $key => $value) $data[$key] = NULL;
            $CI->load->view($view, $data, TRUE);
        }
        return $content;
    }
}

使用可以处理空变量的视图,而不是因为性能问题而使用每个视图调用。

clear_vars(); 很有趣,但它取消了所有变量,而不是当前视图中的变量。

答案 5 :(得分:0)

首先,你的问题不清楚的两件事:

  1. $ this-&gt; prizeddistributor-&gt; isWinner()如何工作
  2. 在某些时候,$赢家是否设置为$ test?
  3. 现在,在那之后......你的控制器不知道“在视图中”会发生什么。您只是回显文本,控制器继续。

    考虑到这一点......我假设$ winner由$ test的值设置,这意味着你的isWinner()函数生成了错误的值。根据你的问题,除了40之外,它应该为$ i的所有值提供null。

    我认为主要观点是您的视图范围不会像您希望的那样影响控制器范围。而且您可能需要更多地了解isWinner()的工作方式。