【发布时间】:2011-12-25 22:26:12
【问题描述】:
我在 PHP 中编写了几行代码来重命名数组中的重复值(灵感来自 from here)。 基本上,我遍历原始数组 ($headers[]),同时使用另一个数组 ($header_test[]) 的键来跟踪重复项。如果有重复,我在 $headers[] 中更改该元素的值。
但奇怪的是,我在 foreach 中通过引用传递并没有得到正确的结果。我必须使用完整的 $array_name[$key] = $new_value 格式实际设置值。这是为什么呢?
(剧透警告:VolkerK 的回答是正确的 - 需要取消设置 $header(foreach "$value" 变量)然后才能正常工作。)
这里:
使用此输入:
$headers = array('Abc 123 ghi',
'dangdarn',
'oops32',
'poss dup',
'poss dup',
'pos _s_ dup',
'bad chars\'& 3% 9'
);
然后应用这个我认为不会影响手头问题的自定义函数:
function mysql_clean_string($string) {
//remove non alnum characters
$string = preg_replace("/[^a-zA-Z0-9\s]/", "_", $string);
// replace 1+ spaces or 1+ '_' with a single '_'
$string = preg_replace("/[ _]+/", "_", $string);
$string = trim($string,'_');
if(strlen($string) > 20) {
$string = substr_replace($string,'',strpos($string,'_',20));
}
$string = strtolower($string);
return $string;
}
array_walk($headers,'mysql_clean_string'); // limit headers to alnum chars
通过引用传递数组值不起作用(请参阅下面的 var_dump()):
$header_test = array();
foreach($headers as &$header) { //passing by reference
$temp = $header;
if(array_key_exists($temp,$header_test)) {
**$header = $header . '_' . $header_test[$header];**
$header_test[$temp]++;
unset($temp);
} else {
$header_test[$temp] = 1;
}
}
//here is the solution VolkerK suggested and it works:
unset($header);
以下是结果不正确的 var_dump 输出(重复值并注意标题 [6] 处的“&”,并且缺少最后一个值):
["headers"]=>
array(7) {
[0]=>
string(11) "abc_123_ghi"
[1]=>
string(8) "dangdarn"
[2]=>
string(6) "oops32"
[3]=>
**string(8) "poss_dup"**
[4]=>
string(10) "poss_dup_1"
[5]=>
string(9) "pos_s_dup"
[6]=>
**&string(8) "poss_dup"**
}
["header_test"]=>
array(6) {
["abc_123_ghi"]=>
int(1)
["dangdarn"]=>
int(1)
["oops32"]=>
int(1)
["poss_dup"]=>
int(2)
["pos_s_dup"]=>
int(1)
["bad_chars_3_9"]=>
int(1)
}
现在这里是可行的,即使用 $original_array[$key] = $new_value 格式:
$header_test = array();
foreach($headers as $key => $header) {
$temp = $header;
if(array_key_exists($temp,$header_test)) {
**$headers[$key] = $header . '_' . $header_test[$header];**
$header_test[$temp]++;
unset($temp);
} else {
$header_test[$temp] = 1;
}
}
var_dump:
["headers"]=>
array(7) {
[0]=>
string(11) "abc_123_ghi"
[1]=>
string(8) "dangdarn"
[2]=>
string(6) "oops32"
**[3]=>
string(8) "poss_dup"
[4]=>
string(10) "poss_dup_1"**
[5]=>
string(9) "pos_s_dup"
**[6]=>
string(13) "bad_chars_3_9"**
}
["header_test"]=>
array(6) {
["abc_123_ghi"]=>
int(1)
["dangdarn"]=>
int(1)
["oops32"]=>
int(1)
["poss_dup"]=>
int(2)
["pos_s_dup"]=>
int(1)
["bad_chars_3_9"]=>
int(1)
}
VolkerK 想出了解决方案。除了他的其他好建议外,关键是在 foreach 循环之后取消设置 $header。
【问题讨论】:
-
我猜你不能 bold 代码,但这就是我试图用 ******asterisks******
-
是的,我在那里运行一个函数。我会将它添加到问题中,但我看不出它会如何影响任何事情,因为它只是使用一些正则表达式来清理字符串。
标签: php foreach pass-by-reference