PHP foreach删除数组元素

时间:2013-01-12 18:57:56

标签: php foreach unset

今天在为博客开发文本分析工具时,我发现PHP行为对我来说非常奇怪,而且无法绕过它。在规范化文本时,我试图删除低于最小长度的单词,所以我在我的规范化方法中写了这个:

if ($this->minimumLength > 1) {
    foreach ($string as &$word)
    {
        if (strlen($word) < $this->minimumLength) {
            unset($word);
        }
    }
}

奇怪的是,这会在我的数组中留下一些低于允许长度的单词。在我整个班级寻找错误后,我试了一下:

if ($this->minimumLength > 1) {
        foreach ($string as $key => $word)
        {
            if (strlen($word) < $this->minimumLength) {
                unset($string[$key]);
            }
        }
    }

瞧!这非常有效。现在,为什么会发生这种情况?我查看了PHP Documentation并说明了:

  

如果在函数内部取消设置了一个被PASSED BY REFERENCE的变量,则只销毁局部变量。调用环境中的变量将保留与调用unset()之前相同的值。

foreach此处是calling environment,因为它有自己的范围吗?

2 个答案:

答案 0 :(得分:2)

不,这里没有函数调用,并且没有通过引用传递变量(您只是在迭代期间通过引用捕获)。

当您通过引用迭代时,迭代变量是原始的别名。当您使用此别名来引用原始别名并修改其值时,更改将在要迭代的数组中保持可见。

但是,当您unset别名时,原始变量不会被“销毁”;只需从符号表中删除别名

foreach ($string as $key => &$word)
{
    // This does not mean that the word is removed from $string
    unset($word);

    // It simply means that you cannot refer to the iteration variable using
    // $word from this point on. If you have captured the key then you can
    // still refer to it with $string[$key]; otherwise, you have lost all handles
    // to it for the remainder of the loop body
}

答案 1 :(得分:1)

当您在if语句中调用unset($word)时,您正在删除$word变量本身,而不对数组$string进行任何更改。