PHP foreach更改原始数组值[重复]
Posted
技术标签:
【中文标题】PHP foreach更改原始数组值[重复]【英文标题】:PHP foreach change original array values [duplicate] 【发布时间】:2013-02-08 02:19:09 【问题描述】:我是多维数组的新手,这让我很烦恼。
我的数组如下:
$fields = array(
"names" => array(
"type" => "text",
"class" => "name",
"name" => "name",
"text_before" => "name",
"value" => "",
"required" => true,
)
)
然后我有一个函数检查这些输入是否被填写,如果需要的话。
function checkForm($fields)
foreach($fields as $field)
if($field['required'] && strlen($_POST[$field['name']]) <= 0)
$fields[$field]['value'] = "Some error";
return $fields;
现在我的问题是这一行
$fields[$field]['value'] = "Some error";
我想更改原始数组的内容,因为我要返回它,但是如何在我的 foreach 循环中获取当前数组的名称(本例中的名称)?
【问题讨论】:
无论您是(或曾经是)新手 - 您都可以从 php 文档中阅读:php.net/manual/en/control-structures.foreach.php 【参考方案1】:使用&
:
foreach($arr as &$value)
$value = $newVal;
unset($value);
&
将数组的值作为引用传递,并且不会创建变量的新实例。因此,如果您更改引用,原始值将会改变。
PHP documentation for Passing by Reference
编辑 2018
这个答案似乎受到互联网上很多人的青睐,这就是为什么我决定添加更多信息和警告。
虽然foreach
(或函数)中的传递引用是一种简洁而简短的解决方案,但对于许多初学者来说,这可能是一个危险的陷阱。
PHP 中的循环没有自己的作用域。 - @Mark Amery
当变量在同一范围内重复使用时,这可能是一个严重的问题。 Another SO question nicely illustrates why that might be a problem.
至于 foreach 依赖于 PHP 5 中的内部数组指针,改变它 在循环内可能会导致意外的行为。 - foreach 的 PHP 文档。
在同一循环的迭代期间取消设置记录或更改哈希值(键)可能会导致 PHP
Foreach 表演。
通常,由于写时复制功能,PHP 更喜欢按值传递。这意味着 PHP 在内部不会创建重复数据,除非它的副本需要更改。 foreach
中的按引用传递是否会提供任何性能改进是值得商榷的。与往常一样,您需要测试您的特定场景并确定哪个选项使用更少的内存和 CPU 时间。有关详细信息,请参阅 NikiC 下面链接的 SO 帖子。
代码可读性。
在 PHP 中创建引用很快就会失控。如果您是新手并且无法完全控制自己在做什么,最好远离参考。有关&
操作员的更多信息,请查看本指南:Reference — What does this symbol mean in PHP?
想进一步了解这部分 PHP 语言的朋友:PHP References Explained
@NikiC 对 PHP foreach
循环内部逻辑的一个非常好的技术解释:How does PHP 'foreach' actually work?
【讨论】:
除了列出的问题之外,我建议在foreach
右括号之后添加unset($value);
,以确保在迭代后引用变量不再可用。 3v4l.org/2V2AQ【参考方案2】:
In PHP, passing by reference (&
) is ... controversial. I recommend not using it unless you know why you need it and test the results.
我建议您执行以下操作:
foreach ($fields as $key => $field)
if ($field['required'] && strlen($_POST[$field['name']]) <= 0)
$fields[$key]['value'] = "Some error";
所以基本上在需要值时使用$field
,在需要更改数据时使用$fields[$key]
。
【讨论】:
很好,这行得通!首先尝试过这样的事情,但我想我搞砸了一些地方:) 现在我将使用你的例子一千次,永远不会忘记! :) 很高兴它有帮助。另外,我建议阅读我链接的文章,以及 foreach 的官方文档(php.net/manual/ro/control-structures.foreach.php) 底线:如果您要更改数组/变量 - 那么您应该使用参考。它更快、更干净、更易读。 我很好奇为什么在foreach
中通过引用传递应该是有争议的?这不像是一个带有隐藏副作用或任何东西的函数调用。
感谢您说“通过引用传递 (&) 是……有争议的”,而不是“不要通过引用传递”或“通过引用传递是邪恶的”。不太可能引发一场火焰战争。 :)【参考方案3】:
function checkForm(& $fields)
foreach($fields as $field)
if($field['required'] && strlen($_POST[$field['name']]) <= 0)
$fields[$field]['value'] = "Some error";
return $fields;
这是我建议通过引用传递的内容
【讨论】:
该技术用于改变原始变量的值。因为 PHP 支持按值传递技术。我们需要在变量前面添加 '&' 字符来说明要通过引用传递的值 那为什么还要返回$fields
?
这是建议的 3 个中最差的答案。对于任何偶然发现此答案的人,请不要设计您的函数来更改数据并返回它。对于原作者:您没有提供任何解释为什么这个解决方案会比其他解决方案更好,或者它是如何工作的......【参考方案4】:
试试这个
function checkForm($fields)
foreach($fields as $field)
if($field['required'] && strlen($_POST[$field['name']]) <= 0)
$field['value'] = "Some error";
return $field;
【讨论】:
不要这样做。我可以看到您的代码至少有两点错误:分配给 $field 不起作用(这样做时 $fields 数组永远不会被修改),并且 return $field 返回单个字段,而不是数组。【参考方案5】:使用foreach($fields as &$field)
- 这样您就可以使用原始数组。
Here 更多的是通过引用传递。
【讨论】:
@RBA 请参考上面的答案 - 他们有更多的细节和更新 - 我有一段时间没有使用 php,所以不知道有任何更新以上是关于PHP foreach更改原始数组值[重复]的主要内容,如果未能解决你的问题,请参考以下文章
PHP中有没有办法在foreach中重新启动循环,或者在开关中更改测试值?
我在 forEach 中更新的变量,返回到它们的原始值 [重复]