2

在我看来,我测试if (isset($winner)). 但是,视图是循环重印的,我无法清除它以进行后续测试。

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

我很欣赏 View 的范围很广,但这似乎是 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是唯一的赢家,尽管控制器总是默认布尔值为假,但视图会将所有 $i > 40 报告为赢家。

更新

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


很多人一直在质疑上面无关的奖品分发者。所以这里有一个更简单的代码示例来说明示例问题

控制器

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

输出

丢失的!丢失的!丢失的!丢失的!丢失的!优胜者!优胜者!优胜者!优胜者!优胜者!

可能的答案:

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

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

这提出了一个很好的观点,也是我对 codeigniter 的欣赏。但问题仍然存在,我们如何才能两者兼得?可能是第四个可选参数来跳过这个捕获?

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

4

6 回答 6

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()如果您包含正在发生的事情或至少提及它正在返回的内容, 这可能有助于获得更好的答案。

于 2013-10-16T18:58:20.530 回答
3

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

$this->load->clear_vars();

在文档中查看

于 2016-04-20T06:59:14.890 回答
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()返回真/假而不是数组。

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

isset($var)如果 . 将返回 false $var === null

于 2013-10-17T17:55:18.697 回答
2

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

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(); 很有趣,但它会取消设置所有变量,而不是当前视图中的变量。

于 2017-06-30T06:56:34.907 回答
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; ?>
于 2013-10-16T19:45:35.967 回答
0

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

  1. $this->prizeddistributor->isWinner() 是如何工作的
  2. $winner 在某个时候设置为 $test 吗?

现在,把它排除在外......您的控制器不知道“在视图中”发生了什么。您只是在回显文本,控制器继续运行。

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

我认为重点是您的视图范围不会像您希望的那样影响控制器范围。您可能需要更深入地了解 isWinner() 的工作原理。

于 2013-10-16T18:59:58.110 回答