我正在尝试使用<select multiple>
或几个具有相同名称的<input type="checkbox">
在PHP中读取由HTML表单生成的查询字符串,并且我希望看到与每个名称关联的所有值。这种形式的一个例子:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Form</title>
</head>
<body>
<h1>Form</h1>
<h2>Select</h2>
<form method="get" action="script.php">
<select multiple name="cantchange" size=5>
<option value="a">Alpha</option>
<option value="b">Bravo</option>
<option value="c">Charlie</option>
<option value="d">Delta</option>
<option value="e">Echo</option>
</select><br>
Ctrl+click to choose multiple items, then
<input type="submit" name="op" value="Submit">
</form>
<h2>Checkbox set</h2>
<form method="get" action="script.php">
<label><input type="checkbox" name="cantchange" value="f"> Foxtrot</label><br>
<label><input type="checkbox" name="cantchange" value="g"> Golf</label><br>
<label><input type="checkbox" name="cantchange" value="h"> Hotel</label><br>
<label><input type="checkbox" name="cantchange" value="i"> India</label><br>
<label><input type="checkbox" name="cantchange" value="j"> Juliett</label><br>
<input type="submit" name="op" value="Submit">
</form>
</body>
</html>
这将生成以下形式的查询字符串:
cantchange=a&cantchange=b&cantchange=c&op=Submit
但是当PHP将此查询字符串解析为$_GET
时,它只会看到每个名称的最后一个值。
“How to get multiple selected values of select box in php?”及其重复内容的答案建议将[]
附加到表单中每个name
或select
元素的input
属性中以制作PHP将值收集到数组中。但这假设解释表单的脚本的作者可以更改表单。这并不总是可行的。即使我可以更改表单,添加括号也会显示应用程序是用PHP编写的,诱使入侵者首先尝试针对服务器的特定于PHP的攻击。</ p>
答案 0 :(得分:0)
如果您无法更改表单,则必须自己完成更多解析查询字符串的工作。首先在&
拆分查询字符串,在=
拆分每个名称 - 值对,并取消名称和值。以下脚本使用重新实现Python's query string parser API的大部分内容的函数来解析这样的表单。
<?php
// Parse query string from <select multiple> without changing the
// form to add brackets to the element's name attribute.
// Implements a subset of Python's urllib.parse.parse_* APIs
// <https://docs.python.org/3/library/urllib.parse.html>
// Copyright 2017 Damian Yerrick
// License: WTFPL v2 <http://www.wtfpl.net/txt/copying/>
/**
* Parses an application/x-www-form-urlencoded string, such as the
* output of http_build_query(), into an array of 2-arrays.
* @param $qs the query string to parse
* @param $keep_blank_values if false, omit pairs whose values are ''
* @return data in the form [[key, value], ...]
*/
function parse_qsl($qs, $keep_blank_values=false) {
$qs = explode("&", $qs);
$out = [];
foreach ($qs as $pair) {
$pair = explode("=", $pair, 2);
if (count($pair) != 2) continue;
$value = urldecode($pair[1]);
if ($keep_blank_values || $value !== '') {
$key = urldecode($pair[0]);
$out[] = [$key, $value];
}
}
return $out;
}
/**
* Parses an application/x-www-form-urlencoded string into an
* associative array from keys to arrays of values.
* @param $qs the query string to parse
* @param $keep_blank_values if false, omit pairs whose values are ''
* @param data in the form [key=>[value, ...], ...]
*/
function parse_qs($qs, $keep_blank_values=false) {
$data = parse_qsl($qs, $keep_blank_values);
$out = [];
foreach ($data as $pair) {
list($key, $value) = $pair;
if (!array_key_exists($key, $out)) {
$out[$key] = [];
}
$out[$key][] = $value;
}
return $out;
}
function hrepr($value) {
return htmlspecialchars(var_export($value, true));
}
?><!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Form</title>
</head>
<body>
<h1>Form</h1>
<pre>
$_GET is <?=hrepr($_GET)?>
Query string is <?=hrepr($_SERVER['QUERY_STRING'])?>
parse_qsl is <?=hrepr(parse_qsl($_SERVER['QUERY_STRING']))?>
parse_qs is <?=hrepr(parse_qs($_SERVER['QUERY_STRING']))?>
</pre>
</body>
</html>