在我看来,我测试if (isset($winner))
.但是,该视图是循环重新打印的,我无法清除它以进行后续测试。
如何实例化新视图或清除/取消设置其控制器给出的变量?
我很欣赏视图的范围很广,但这似乎是 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 报告为赢家,尽管控制器始终默认布尔值为假。
更新
我知道测试是否(空($test))允许视图正确报告。但是,我的问题是如何取消设置该变量(并将其从内存中清除)。这个问题很大程度上源于使用HMVC(模块化代码点火器)时的其他类似问题。但是,在此处发布该代码将过于复杂,无法说明相同的范围问题。
许多人一直在质疑上面无关紧要的奖品分销商。因此,这里有一个更简单的代码示例来说明 sampe 问题:
控制器
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>"; ?>
输出
失去!失去!失去!失去!失去!胜利者!胜利者!胜利者!胜利者!胜利者!
可能的答案:
我已经研究了 codeigniter 的system/core/Loader.php
,并找到了_ci_load
第 800 行周围缓存变量的函数。他们的推理是:
您可以使用专用的 $this->load_vars() 设置变量 函数或通过此函数的第二个参数。我们将合并 两种类型并缓存它们,以便嵌入到其他中的视图 视图可以访问这些变量。
这提出了一个非常好的观点,也是我对codeigniter的欣赏。但问题仍然存在,我们怎样才能两者兼得?可能是跳过此捕获的第 4 个可选参数?
前任。 loader->view("testScope", $winner, TRUE, FALSE);
????
使用 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()
中发生的事情或至少提及它正在返回的内容,则可能会有所帮助。
在 Codeigniter 3 中,您可以使用方法
$this->load->clear_vars();
在文档中查看
所以你似乎知道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。
如果$var === null
,isset($var)
将返回 false。
您可以创建一个帮助程序函数来加载视图并在之后销毁参数。
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(); 很有趣,但它取消设置所有变量,而不是当前视图中的变量。
您是否尝试过直接从视图中获取数据?
控制器
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; ?>
首先,您的问题不清楚两件事:
- $this->prizeddistributor->isWinner() 如何运作
- $winner是否设置为在某个时候$test?
现在,有了这个...您的控制器不知道"在视图中"会发生什么。 您只需回显文本,控制器将继续运行。
考虑到这一点...我假设$winner是由 $test 中的值设置的,这意味着您的 isWinner() 函数生成了错误的值。 根据您的问题,它应该为除 40 之外的所有 $i 值提供 null。
我认为重点是您的视图范围不会像您希望的那样影响控制器范围。 而且你可能需要更深入地了解isWinner()是如何工作的。