Estoy tratando de leer en PHP una cadena de consulta generada por un formulario HTML usando <select multiple>
o varios <input type="checkbox">
con el mismo nombre, y quiero ver todos los valores asociados con cada nombre. Un ejemplo de tal forma:
<!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>
Esto produce una cadena de consulta de la siguiente forma:
cantchange=a&cantchange=b&cantchange=c&op=Submit
Pero cuando PHP analiza esta cadena de consulta en $_GET
, solo ve el último valor con cada nombre.
Las respuestas a " ¿Cómo obtener múltiples valores seleccionados del cuadro de selección en php? " y sus duplicados recomiendan agregar []
al atributo de name
de cada elemento de input
o select
en el formulario para hacer que PHP recopile valores en una matriz. Pero esto supone que el autor del guión que interpreta el formulario puede cambiar el formulario. Esto no siempre es posible. E incluso cuando puedo cambiar el formulario, agregar los corchetes revela que la aplicación está escrita en PHP, lo que tienta a los intrusos a intentar primero exploits específicos de PHP contra el servidor.
Si no puede cambiar el formulario, tendrá que hacer más del trabajo de analizar las cadenas de consulta usted mismo. Primero divida la cadena de consulta en &
, divida cada par de nombre-valor en =
y elimine el escape del nombre y el valor. La siguiente secuencia de comandos analiza formularios como este utilizando funciones que vuelven a implementar gran parte de la API del analizador de cadenas de consulta de Python .
<?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>