从包含重复键的查询字符串/ jQuery.serialize() 解析表单提交数据而不丢失值

发布于 2024-12-27 04:31:57 字数 840 浏览 1 评论 0原文

我试图找出如何处理可能重复的数组键。

我有这个带有选择下拉列表的表单,可以选择多个选项(超过 1 个)。我正在使用 jQuery.serialize() 来序列化提交时的表单。

多选元素的序列化字符串如下所示:

select=1&select=2&select=3 // assuming 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;
}

这一切都适用于其余的表单元素,但是当涉及到 select 元素时,它只选择最后选择的键/值对。所以我的数组现在看起来像这样:

Array ( [select_element] => 3)

我需要的是它看起来像:

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

所以我想我要问的是基于我的代码,我如何检查一个键是否已经存在,如果存在,则附加到 <代码>$值。

I am trying to figure out how I can handle possible duplicate array keys.

I have this form with a select dropdown which can select multiple options (more than 1). And I am using jQuery.serialize() to serialize the form on submit.

The serialized string for a multi-select element would look like so:

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

Now in the PHP side, I have the following code to handle the "saving" part into a database.

$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;
}

This all works for the rest of the form elements, but when it comes to the select element, it only picks the last selected key/value pair. So my array now looks like this:

Array ( [select_element] => 3)

What I need, is for it to look like:

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

So I guess what I am asking is based on my code, how can I check if a key already exists and if it does, append to the $value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

隱形的亼 2025-01-03 04:31:57

如果您可以修改客户端代码,我宁愿将 select 的名称更改为 select[],这样它将在您的服务器中解析为数组脚本。

If you can modify the client-side code, I would rather change the name of the select to select[], that way it will be parsed as an array in your server script.

世态炎凉 2025-01-03 04:31:57

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');

如果没有这些方括号,PHP 将使用给定键的最后一个值。请参阅 PHP 和 HTML 中的此问题常见问题解答

如果您无法控制 POSTed 接口(例如,您无法向表单添加方括号),您可以自己从 php://input 解析 POST 输入,然后重写或忽略 $_POST 变量。

(但请注意,对于 multipart/form-data 输入没有解决方法,因为 php://input 在这些输入中不可用select=1select=2 将完全且无法挽回地丢失。)

PHP has its own way of encoding arrays into application/x-www-form-urlencoded strings.

PHP's deserialization of x-www-form-urlencoded is implemented by parse_str(). You can think of PHP as running these lines at the beginning of every request to populate $_GET and $_POST:

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

parse_str() creates arrays from the query string using a square-bracket syntax similar to its array syntax:

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

This will be deserialized to:

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

Absent those square brackets, PHP will use the last value for a given key. See this question in the PHP and HTML FAQ.

If you can't control the POSTed interface (e.g., you're not able to add square-brackets to the form), you can parse the POST input yourself from php://input and either rewrite or ignore the $_POST variable.

(Note, however, that there is no workaround for multipart/form-data input, because php://input is not available in those cases. The select=1 and select=2 will be completely and irretrievably lost.)

放低过去 2025-01-03 04:31:57

好的,我可以使用以下代码解决这个问题:

    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;
    }
}

这实际上会将用逗号分隔的值串在一起,然后可以将其分解为数组。

Ok, I was able to resolve this issue by using the following code:

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

So now the loop looks like this:

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;
    }
}

This will essentially string up the value together separated by a comma which can then be exploded out into an array later.

眼泪也成诗 2025-01-03 04:31:57

您不能有多个同名的密钥...它们是唯一密钥。它所做的就是设置 select = 1,然后 select = 2,然后 select = 3,最终得到的值为 3。

如果你想在选择菜单中允许多个选择,你应该更改元素的名称,以便它将数据作为数组而不是多个字符串提交:

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

这应该会导致类似这样的结果:

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

当 PHP 请求该数据时,它已经是一个数组:

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

You can't have multiple keys with the same name... They're unique keys. What it's doing is setting select = 1, then select = 2, then select = 3 and you end up with your final value of 3.

If you want to allow multiple choices in your select menu, you should change the name of the element so that it submits that data as an array, rather than multiple strings:

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

which should result in something like this instead:

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

and when PHP requests that data, it will already be an array:

$data = $_POST['select'];
echo print_r($data); // Array(1, 2, 3)
咿呀咿呀哟 2025-01-03 04:31:57

您应该更改客户端代码以发送增强值:array.join(","); 并在 PHP 端使用它。因为当您的数据到达脚本时,其他值已经丢失。

You should change your client-side code to send the augmented value: array.join(","); and use that in your PHP side. Because when your data reaches your script, the other values have already been lost.

柏林苍穹下 2025-01-03 04:31:57

这应该会给你你需要的解决方案

$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;
    }
}

This should give you the solution you require

$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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文