2012-01-14 3 views
2

Я пытаюсь выяснить, как я могу обрабатывать возможные дубликаты ключей массива. Да, я знаю, что ключи дубликатов массивов НЕВОЗМОЖНО, но голые со мной на мгновение.PHP, как обрабатывать возможные дубликаты ключей массива?

У меня есть эта форма с выпадающим списком, в котором можно выбрать несколько опций (более 1). И я использую jQuery.serialize(), чтобы сериализовать форму на submit.

Сериализованная строка для множественного выбора элемента будет выглядеть так:

select=1&select=2&select=3 // assumming I selected first 3 options. 

Теперь в стороне PHP, у меня есть следующий код для обработки «экономия» части в базу данных.

$form_data = $_POST['form_items']; 

$form_data = str_replace('&','####',$form_data); 
$form_data = urldecode($form_data); 
$arr = array(); 
foreach (explode('####', $form_data) as $part) { 
     list($key, $value) = explode('=', $part, 2); 

    $arr[$key] = $value; 
} 

Ok все это работает для всех остальных элементов формы, но когда дело доходит до выбора элемента, он выбирает только последнюю пару выбранный ключ/значение. Так что мой массив теперь выглядит следующим образом:

Array ([select_element] => 3) 

Что мне нужно, это для того, чтобы выглядеть следующим образом:

Array ([select_element] => '1,2,3') 

Так что я думаю, что я прошу основана на моем коде, как я могу проверить если ключ уже существует, и если это так, добавьте его к $value.

+1

http://www.php.net/manual/en/function.parse-str.php#76792 – Wrikken

ответ

1

Хорошо, я был в состоянии чтобы решить эту проблему, используя следующий код:

if (array_key_exists($key, $arr)) { 
     $arr[$key] = $arr[$key].','.$value; 
    } else { 
     $arr[$key] = $value; 
    } 

Так что теперь цикл выглядит следующим образом:

foreach (explode('####', $form_data) as $part) { 
    list($key, $value) = explode('=', $part, 2); 

    if (array_key_exists($key, $arr)) { 
     $arr[$key] = $arr[$key].','.$value; 
    } else { 
     $arr[$key] = $value; 
    } 
} 

Это, по существу, приведет к объединению значения, разделенного запятой, которая затем может быть взорвана в массив позже.

0

Вы должны изменить свой код на стороне клиента, чтобы отправить увеличенное значение: array.join(","); и использовать его на своей стороне PHP. Потому что, когда ваши данные достигают вашего скрипта, другие значения уже потеряны.

+0

«Когда ваши данные достигнут вашего скрипта, другие значения уже потеряны». Почему это так? = –

+0

@Niklas: Я предполагаю, что Milad означает, что они не будут в массиве '$ _GET', но они могут быть получены из' $ _SERVER ['QUERY_STRING'] '. – Wrikken

+0

Поскольку, декодируя полученные данные в массивы PHP, вы передаете преобразование в механизм PHP, который заменит элементы одним и тем же ключом в массивах. Таким образом, только последнее появление пережитит преобразование. –

5

Если вы можете изменить код на стороне клиента, я бы скорее изменил имя select на select[], таким образом он будет анализироваться как массив в вашем скрипте сервера.

+0

Я думал о том, чтобы сделать это таким образом, но это не сработает, когда вы сериализуете элементы формы с помощью jQuery. –

+0

Я думаю, что для jquery> 1.4 'serialize' сохранит скобки. Если вы хотите поместить его динамически на вход или какую-либо другую переменную для его отправки, вы можете использовать 'decodeURIComponent' в результате, а затем на сервере вы будете использовать' parse_str' для этой переменной. – rabusmar

+0

Используя текущий jQuery 2+, используя name = "select []" отлично работает с parse_str. Спасибо за подсказку;) –

0

У вас не может быть нескольких ключей с тем же именем ... Они уникальные ключи. Что она делает это установка select = 1, то select = 2, то select = 3 и вы в конечном итоге с окончательной стоимостью 3.

Если вы хотите разрешить несколько вариантов в вашем меню выбора, вы должны изменить имя элемента так, чтобы она представляет эти данные в виде массива, а не несколько строк:

<select name="select[]" multiple="multiple"> 

, которые должны привести к чему-то вроде этого, вместо:

select[]=1&select[]=2&select[]=3 

и когда PHP запрашивает эти данные, он будет ALRE отовы быть массивом:

$data = $_POST['select']; 
echo print_r($data); // Array(1, 2, 3) 
-1

Это должно дать вам решение вам требуется

$form_data = str_replace('&','####',$form_data); 
$form_data = urldecode($form_data); 
$arr = array(); 

foreach (explode('####', $form_data) as $part) { 
    list($key, $value) = explode('=', $part, 2); 

    if (isset($arr[ $key ])) { 
     $arr[$key] = ','.$value; 
    } else { 
     $arr[$key] = $value; 
    } 
} 
1

PHP имеет свой собственный способ кодирования массивов в application/x-www-form-urlencoded строк.

От десериализации PHP x-www-form-urlencoded реализован parse_str().Вы можете думать о PHP, как работает эти строки в начале каждого запроса, чтобы заполнить $_GET и $_POST:

parse_str($_SERVER['QUERY_STRING'], $_GET); 
parse_str(file_get_contents('php://input'), $_POST); 

parse_str() создает массивы из строки запроса с помощью синтаксиса квадратных кронштейн, похожий на его синтаксис массива:

select[]=1&select[]=2&select[]=3&select[key]=value 

Это будет десериализация для:

array('1', '2', '3', 'key'=>'value'); 

Absent этих квадратных скобок, PHP будет использовать последнее значение для заданного ключа. См. this question in the PHP and HTML FAQ.

Если вы не можете контролировать публикуемый интерфейс (например, вы не могут добавить квадратные скобки в форму), вы можете разобрать на входе POST себя от php://input и либо переписать или игнорировать переменную $_POST.

(Заметим, однако, что не существует временного решения проблемы для multipart/form-data ввода, поскольку php://input не доступен в тех случаях. В select=1 и select=2 будет полностью и безвозвратно утеряны.)

+0

Спасибо за объяснение, но могли бы вы показать мне, как это может быть включено в мой код? Я не уверен, заявляю ли вы, не следует ли мне использовать функцию списка и использовать parse_str? –

+0

Честно говоря, ваш код не имеет никакого смысла. Если у вас есть контроль над своей формой, вы должны изменить ее, чтобы следовать правилам PHP, и весь ваш код должен быть ненужным. Если у вас нет контроля над своей формой, вы должны показать нам необработанное тело POST, чтобы мы могли предложить что-то более конкретное. –

Смежные вопросы