Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

405
Views
Parse query string with multiple same-name values (checkbox, select multiple) without changing the form

I'm trying to read in PHP a query string generated by an HTML form using <select multiple> or several <input type="checkbox"> with the same name, and I want to see all values associated with each name. An example of such a form:

<!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>

This produces a query string of the following form:

cantchange=a&cantchange=b&cantchange=c&op=Submit

But when PHP parses this query string into $_GET, it sees only the last value with each name.

Answers to "How to get multiple selected values of select box in php?" and its duplicates recommend appending [] to the name attribute of each select or input element in the form to make PHP collect values into an array. But this assumes that the author of the script that interprets the form can change the form. This isn't always possible. And even when I can change the form, adding the brackets reveals that the application is written in PHP, tempting intruders to try PHP-specific exploits against the server first.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

If you can't change the form, you'll have to do more of the work of parsing the query strings yourself. First split the query string at the &, split each name-value pair at the =, and unescape the name and value. The following script parses forms like this using functions that reimplement much of 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>
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!