Я написал несколько строк кода в PHP, чтобы переименовать повторяющиеся значения в массиве (с некоторым вдохновением отсюда ).
По сути, я просматриваю исходный массив ($ headers []), используя ключи другого массива ($ header_test []) для отслеживания дубликатов. Если есть дубликат, я изменяю значение этого элемента в $ headers [].
Но странная вещь заключается в том, что я не получал правильных результатов, передавая по ссылке в foreach. Я должен был установить значения, используя полный формат $ array_name [$ key] = $ new_value. Почему это так?
(Оповещение о спойлере: ответ VolkerK верный - необходимо сбросить заголовок $ (переменная 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.