【问题标题】:PHP reference acting strangePHP 参考行为怪异
【发布时间】:2012-08-26 00:18:28
【问题描述】:

我对 PHP 的引用 (&) 有一个奇怪的问题。

假设我有一个看起来像这样的表单:

<form name="form1" id="form1" method="post">
   Name: <input type="text" name="name" /><br />
   Email: <input type="text" name="email" /><br />
   Location: <input type="text" name="location" /><br />
   Phone Number: <input type="text" name="phonenumber" /><br />
</form>

然后我将该表单提交给另一个 PHP 处理程序。处理程序会这样做:

foreach($_POST as $name => &$value)
{
    //more code here
}
echo $_POST['phonenumber']; //Returns value of $_POST['location'] for some reason

有人可以向我解释为什么电话号码的价值会是任何位置的价值吗?即使 foreach 内部没有代码,它仍然会这样做。

编辑:

对于那些想知道 foreach 内部发生了什么或者我为什么要这样做的人来说,这是因为它是一种干净的方式来转义提交给处理程序的所有数据,而不是手动一次执行一个变量,尤其是当你有动态输入进来时。所以像这样:

foreach($_POST as $name => &$value)
{
    $value = preg_replace( "/[<>#$%]/", "", $value);
    $value = preg_replace('/\s\s+/', ' ', $value);
}

除了我上面提到的问题之外,它工作得很好。

【问题讨论】:

  • 可能是 $_POST 的构造方式吗?尝试将其分配给您自己的数组,然后在该数组上运行 foreach(带引用)。
  • 即使 foreach 内部没有代码,它仍然会这样做。 什么?
  • 在我看来,不可能。你用的是什么 PHP 版本?
  • 您是稍后分配给&amp;$value,还是使用相同的名称多次执行此循环? (基本上,像这样的循环在 PHP 中很糟糕,而且真的很痛,所以尽量不要这样做。)
  • 循环内的代码不相关。我已经删除了它,它仍然做同样的事情——因此是我帖子中的最后一句话。

标签: php post reference foreach


【解决方案1】:

您是否可能会重复它两次,一次有引用,一次没有?这有很大的不同:

$array = [1, 2];

foreach($array as &$value);
echo implode(',', $array); # 1, 2

foreach($array as $value);
echo implode(',', $array); # 1, 1

And here's a demo. 修复是unset $value between the loops

$array = [1, 2];

foreach($array as &$value);
echo implode(',', $array); # 1, 2
unset($value);

foreach($array as $value);
echo implode(',', $array); # 1, 2

【讨论】:

  • 你把它钉在了头上。我迭代了两次,一次有参考,一次没有。使用 unset 有效。
  • 好的。为什么这会有所作为?为什么通过引用从数组中获取 $value 会导致它在循环范围之外存活?
  • @DanielBingham:PHP 没有循环范围。 &amp;$value 在循环后仍然引用数组中的最后一项,因此分配给它(作为foreach 循环 does 在 PHP 中)将更改最后一项。总结一下:PHP很奇怪。
  • @minitech:所以循环变量总是保持在循环之后的范围内?何时通过值而不是引用分配它们并不重要,因为它们只是在下次使用时被覆盖?记住内存问题可能很好。
  • 这有点反常。我不认为 PHP 在 for 循环中以这种方式工作。
【解决方案2】:

我很确定您对 foreach 循环中的引用值感到困惑。您不应该使用它的另一个原因。如果您真的认为循环后至少需要unset() value。看看这个例子:http://codepad.viper-7.com/VCOI2O(注意第一个转储中电话号码的&amp;,它仍然被引用)。

但我认真地认为你应该重新考虑通过参考来做这件事。相反,只需在循环中访问您需要的项目:

foreach($_POST as $name => $value)
{
    // do with the value what you want
    $_POST[$name] = $value;
}

但是,完全不更改$_POST 超级全局会更好。当您稍后尝试访问它并且其中的某些内容已更改时,它只会让其他人和您自己感到困惑。

【讨论】:

  • 你是对的。我需要使用未设置。阅读我上面的编辑,了解我使用参考的理由。
  • 正如我所说,仍然不喜欢通过引用来完成。
【解决方案3】:

如果您要重新分配 $value 变量,则可能会发生这种情况。例如,在这种情况下,最后一次迭代(电话号码)将等于位置值,因为 &amp; 意味着如果您分配给它,该值将被更新:

<?php

$i = 0;

foreach($_POST as $name => &$value) {
    if ($i > 2) {
        $value = $temp;
    }
    $i++;

    $temp = $value;
    echo $value;
}

?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    相关资源
    最近更新 更多