5

今天在为博客开发文本分析工具时,我发现 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 文档,它指出:

如果通过引用传递的变量在函数内部是 unset(),则只有局部变量被破坏。调用环境中的变量将保留与调用 unset() 之前相同的值。

是否因为它有自己的范围而foreach在这里充当?calling environment

4

2 回答 2

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
}
于 2013-01-12T19:02:24.633 回答
1

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

于 2013-01-12T19:00:14.930 回答