访问PHP foreach循环外部的变量

访问PHP foreach循环外部的变量,php,refactoring,foreach,Php,Refactoring,Foreach,在我正在编写的一些代码中,我注意到有几个变量正在从foreach循环外部访问 这可以在这个特定应用程序的codeigniter视图文件中看到 例如,视图文件: <?php foreach ($items as $row): endforeach; // HTML / PHP code... <td> <?php echo form_checkbox('option_1','1', FALSE); ?> <?php echo form_

在我正在编写的一些代码中,我注意到有几个变量正在从
foreach
循环外部访问

这可以在这个特定应用程序的codeigniter视图文件中看到

例如,视图文件:

<?php
foreach ($items as $row):
endforeach;

// HTML / PHP code...

 <td>
     <?php echo form_checkbox('option_1','1', FALSE); ?>
     <?php echo form_hidden('weight_unit', $row->weight_unit); ?>
 </td>
// etc...

//等等。。。
这是可行的(即,没有错误),但我想知道这是否会被视为一种不好的做法,如果是,为什么?(范围等)

有人对此有意见吗?是否应该只在相应的循环中调用变量

我注意到的另一个问题是,视图文件的几个部分是否需要一个变量:我应该重构为具有多个循环,还是应该有一个
foreach/endforeach
和文件的开始/结束


任何建议都将不胜感激。谢谢。

我想说这是非常糟糕的做法-如果稍后(几周内)您遇到同一段代码,并且您需要另一个
foreach
在实际的
foreach
和您的表之间完全不同的记录类型上您的
$row
变量将具有完全不同的含义-当添加更多代码时,这段代码非常容易受到副作用的影响

此外,将来PHP很可能不再支持这种行为(这只是我的一个假设,因为正如您所提到的,$row变量超出了您使用它的范围)

作为一些一般原则:

  • 使用尽可能少的全局变量-它们很难跟踪、维护和确保正确的值
  • 尽可能减少变量的范围,并且只在非常明确的范围内使用它们
  • 避免边缘用例和在其他语言中完全不自然的所谓特性
  • 最后,但并非最不重要的一点是,如果代码很难编写,那么就要避免这一原则——这一原则不会确保你获得工作,只会让你的同事感到讨厌

我考虑这样做的唯一原因是查找数组的末尾,以便将其最后一个成员存储在变量中

你可以用它来做得更清楚


$row
将是数组中的最后一项,或在到达其他代码时取消设置

那是你想要的吗?如果是这样的话,那么就其本身而言,这并不是一个坏习惯。但你至少应该记录下这种行为的意图,因为它不是直观的

更好的实践是:

foreach ($foo as $bar) 
{
  // do something
}
$last_bar = isset($bar) ? $bar : null;
很明显,您的意思是使用
$last\u bar
做一些事情

我注意到的另一个问题是,视图文件的几个部分是否需要变量

如果必须在视图中的不同位置迭代循环,那么就可以了


但是,如果您只需要某个数组中的某一信息,那么您应该将其粘贴到一个易于访问的变量中,并使用该变量。

这是一种不好的做法。如果记录集的长度超过一项,则您将遍历所有记录(即使您在循环中什么都不做),然后仅使用最后一条记录。我不使用CI,但如果这是一个记录集对象,则应该有某种方式来访问RS中的第一条/最后一条记录或任何其他索引位置。如果您要查找特定记录,则应使用这些方法。如果只是一个数组,如果不需要保持数组完整,可以使用
array\u pop
,如果需要,可以使用
end


此外,在长集的相同上下文中,如果不是最后一条记录,则如果记录集长度发生变化,则可能会产生不可预见的后果。

完全同意。如果循环体是空的,那么进行迭代肯定是一种浪费。这是一个有趣的点——有一个文件,其中在顶部调用了一个空的
foreach/endforeach
,并且从文件中间/底部的空循环调用了几个变量(不仅仅是最后一个数组成员)——它可以工作。这有什么意义吗?@torr,你说的“变量”是什么意思?它们看起来像什么?迭代只提供了一个新项:
$row
,这是最后一项。对不起,我指的是数组的其他成员--只需重新检查代码,您是对的,这个方法只会调用最后一个成员——我被代码弄糊涂了,因为有另一个空的foreach循环将其他数组成员分配给其他被访问的变量。我同意这不应该这样做——请参阅我对@alex的评论——看起来访问的不仅仅是最后一个成员,还有其他变量(成功地)从这个代码中的空循环请参见上面-关于代码是如何设置的有一些混淆-这个(糟糕的)实践将只提供您所说的最后一个成员
foreach ($foo as $bar) 
{
  // do something
}
$last_bar = isset($bar) ? $bar : null;