Haga que PHP deje de reemplazar '.' caracteres en matrices $ _GET o $ _POST?


76

Si paso variables de PHP con .sus nombres a través de $ _GET, PHP las reemplaza automáticamente con _caracteres. Por ejemplo:

<?php
echo "url is ".$_SERVER['REQUEST_URI']."<p>";
echo "x.y is ".$_GET['x.y'].".<p>";
echo "x_y is ".$_GET['x_y'].".<p>";

... genera lo siguiente:

url is /SpShipTool/php/testGetUrl.php?x.y=a.b
x.y is .
x_y is a.b.

... mi pregunta es la siguiente: ¿hay alguna forma de que esto se detenga? No puedo por mi vida averiguar qué he hecho para merecer esto

La versión de PHP con la que estoy ejecutando es 5.2.4-2ubuntu5.3.


.. ¿Por qué no convierte todos los puntos en algún tipo de token, como por ejemplo, en (~ # ~) y luego lo publica? Cuando recibas las vars, puedes reconvertirlas de nuevo ... Esto se debe a que a veces NECESITAMOS colocar guiones bajos ... y los perderíamos si reconvirtiéramos todos los "_" a "." S ...
Fernando

Desde la consulta de recuperación en sí, puede concatear el nombre de usuario como "concat (nombre, '_', apellido) como nombre de usuario.
Kaspar Mary

@Kaspar Mary ... la base de datos está configurada para tener columnas de nombre de usuario y estado y los nombres de usuario se almacenan como firstname.lastname, por lo que no puedo usar ningún concat en sql ya que ya están concat-ed con a.
Rob

@Crisp ¡Gracias por el comentario! (at) Rob problema interesante
hek2mgl

¿Por qué no hay un comentario para eliminar? :)
Chris Prince

Respuestas:


66

Aquí está la explicación de PHP.net de por qué lo hace:

Puntos en nombres de variables entrantes

Normalmente, PHP no modifica los nombres de las variables cuando se pasan a un script. Sin embargo, debe tenerse en cuenta que el punto (punto, punto) no es un carácter válido en un nombre de variable PHP. Por la razón, míralo:

<?php
$varname.ext;  /* invalid variable name */
?>

Ahora, lo que ve el analizador es una variable llamada $ varname, seguida del operador de concatenación de cadenas, seguido de la cadena desnuda (es decir, cadena sin comillas que no coincide con ninguna clave conocida o palabras reservadas) 'ext'. Obviamente, esto no tiene el resultado esperado.

Por esta razón, es importante tener en cuenta que PHP reemplazará automáticamente cualquier punto en los nombres de las variables entrantes con guiones bajos.

Eso es de http://ca.php.net/variables.external .

Además, según este comentario, estos otros caracteres se convierten en guiones bajos:

La lista completa de caracteres de nombre de campo que PHP convierte a _ (subrayado) es la siguiente (no solo el punto):

  • chr (32) () (espacio)
  • chr (46) (.) (punto)
  • chr (91) ([) (corchete abierto)
  • chr (128) - chr (159) (varios)

Entonces, parece que está atascado, por lo que tendrá que convertir los guiones bajos de nuevo en puntos en su script usando la sugerencia de dawnerd (aunque solo usaría str_replace ).


20
Esta es una gran explicación de por qué , pero no responde a la pregunta original de "¿hay alguna manera de hacer que se detenga?" otras respuestas a continuación proporcionan una respuesta a la pregunta original.
El Yobo

1
@ElYobo, @JeremyRuten; buena explicación de por qué? Estoy usando PHP 5.4 y PHP todavía está haciendo esto. También me encantaría saber por qué aún no está en desuso. Solo veo dos razones para mantenerlo; register_globals (obsoleto desde 5.3), y por conveniencia al ~ hacer lo que hace register globals manualmente (en cuyo caso la carga debería recaer en la persona que hace eso para mapear los nombres de var como mejor les parezca en mi opinión).
semiseguro

1
¿Compatibilidad con versiones anteriores, supongo? Buen punto, con los registros globales siguiendo el camino del dodo, esta extraña "funcionalidad" podría ser similar.
El Yobo

Con php7, los registros globales ya se perdieron en el ocaso, pero el problema sigue presente.
magallanes

59

Pregunta respondida hace mucho tiempo, pero en realidad hay una mejor respuesta (o solución alternativa). PHP le permite en el flujo de entrada sin procesar , por lo que puede hacer algo como esto:

$query_string = file_get_contents('php://input');

que le dará la matriz $ _POST en formato de cadena de consulta, puntos como deberían ser.

Luego puede analizarlo si lo necesita (según el comentario de POSTER )

<?php
// Function to fix up PHP's messing up input containing dots, etc.
// `$source` can be either 'POST' or 'GET'
function getRealInput($source) {
    $pairs = explode("&", $source == 'POST' ? file_get_contents("php://input") : $_SERVER['QUERY_STRING']);
    $vars = array();
    foreach ($pairs as $pair) {
        $nv = explode("=", $pair);
        $name = urldecode($nv[0]);
        $value = urldecode($nv[1]);
        $vars[$name] = $value;
    }
    return $vars;
}

// Wrapper functions specifically for GET and POST:
function getRealGET() { return getRealInput('GET'); }
function getRealPOST() { return getRealInput('POST'); }
?>

Muy útil para los parámetros OpenID, que contienen tanto '.' y '_', ¡cada uno con un cierto significado!


5
Para que esto funcione con los parámetros GET, reemplace file_get_contents("php://input")con $_SERVER['QUERY_STRING'].
Sarel Botha

Y puede hacer lo mismo con las cookies usando$_SERVER['COOKIES']
Marcin

4
Este es un buen comienzo, pero tiene un par de problemas. No maneja valores de matriz (por ejemplo, foo.bar [] = blarg no terminará como una matriz, terminará como una variable escalar llamada foo.bar []). También tiene mucha sobrecarga ya que reprocesa todos los valores, independientemente de si hay un período en ellos o no.
El Yobo

Vea mi solución a continuación , que soluciona los problemas con la implementación de Rok.
El Yobo

Por alguna razón $ query_string = file_get_contents ('php: // input'); devuelve una cadena vacía para mí.
Chris Prince

27

Resaltando una respuesta real de Johan en un comentario anterior: acabo de envolver toda mi publicación en una matriz de nivel superior que evita por completo el problema sin requerir un procesamiento pesado.

En la forma en que lo haces

<input name="data[database.username]">  
<input name="data[database.password]">  
<input name="data[something.else.really.deep]">  

en vez de

<input name="database.username"> 
<input name="database.password"> 
<input name="something.else.really.deep">  

y en el controlador de publicaciones, simplemente desenvuélvalo:

$posdata = $_POST['data'];

Para mí, este fue un cambio de dos líneas, ya que mis puntos de vista estaban completamente basados ​​en plantillas.

FYI. Estoy usando puntos en mis nombres de campo para editar árboles de datos agrupados.


4
De hecho, una solución muy elegante y práctica, con el beneficio adicional de mantener los datos del formulario con un buen espacio de nombres.
robinmitra

1
Esto resuelve completamente el problema y debería haber sido la respuesta aceptada.
Brian Klug

20

El funcionamiento de esta función es una buena idea que se me ocurrió durante mis vacaciones de verano de 2013.

Cumple con los estándares y tiene soporte profundo para arreglos, por ejemplo a.a[x][b.a]=10. Se utiliza parse_str()detrás de escena con un preprocesamiento específico.

function fix($source) {
    $source = preg_replace_callback(
        '/(^|(?<=&))[^=[&]+/',
        function($key) { return bin2hex(urldecode($key[0])); },
        $source
    );

    parse_str($source, $post);

    $result = array();
    foreach ($post as $key => $val) {
        $result[hex2bin($key)] = $val;
    }
    return $result;
}

Y luego puedes aplicarlo así, dependiendo de la fuente:

$_POST   = fix(file_get_contents('php://input'));
$_GET    = fix($_SERVER['QUERY_STRING']);
$_COOKIE = fix($_SERVER['HTTP_COOKIE']);

Para PHP por debajo de 5.4: use en base64_encodelugar de bin2hexy en base64_decodelugar de hex2bin.


Gracias por esto. Actualícelo también para arrays profundos a [2] [5] si tiene tiempo.
Johan

@Johan, las matrices profundas funcionan. a[2][5]=10produce array(1) { ["a"]=> array(1) { [2]=> array(1) { [5]=> string(2) "10" } } }.
Rok Kralj

1
Oh, lo tengo, de hecho lo hace, solo lo probé. Php no convierte puntos, etc. dentro de índices de matriz, solo el nivel superior del nombre de matriz tiene problemas: php_touches_this [nochangeshere] [nochangeshere]. Excelente. Gracias.
Johan

Me encantaría ver sus puntos de referencia, ya que eso entra en conflicto con las pruebas que hice hace unos meses. Además, acabo de encontrarme con la situación en la que necesito manejar períodos en campos de archivos publicados, que aún no abordan las respuestas; ¿algunas ideas?
El Yobo

Los verá muy pronto, actualmente no tiene tiempo, pero puede presentar el suyo. * Las cargas de archivos requieren el tipo multipart / form-data, que no se pasa a php: // input. Por lo tanto, esto todavía es muy complicado de hacer. Ver: stackoverflow.com/questions/1361673/get-raw-post-data
Rok Kralj

7

Esto sucede porque un punto es un carácter no válido en el nombre de una variable, la razón por la cual se encuentra muy profundamente en la implementación de PHP, por lo que no hay soluciones fáciles (todavía).

Mientras tanto, puede solucionar este problema de la siguiente manera:

  1. Acceder a los datos sin procesar de la consulta a través php://inputde datos POST o $_SERVER['QUERY_STRING']de datos GET
  2. Usando una función de conversión.

La siguiente función de conversión (PHP> = 5.4) codifica los nombres de cada par clave-valor en una representación hexadecimal y luego realiza una regular parse_str(); una vez hecho esto, revierte los nombres hexadecimales a su forma original:

function parse_qs($data)
{
    $data = preg_replace_callback('/(?:^|(?<=&))[^=[]+/', function($match) {
        return bin2hex(urldecode($match[0]));
    }, $data);

    parse_str($data, $values);

    return array_combine(array_map('hex2bin', array_keys($values)), $values);
}

// work with the raw query string
$data = parse_qs($_SERVER['QUERY_STRING']);

O:

// handle posted data (this only works with application/x-www-form-urlencoded)
$data = parse_qs(file_get_contents('php://input'));

Sin embargo, ¿qué pasaría si esto tuviera que usarse para otra cosa que se envió y realmente necesito el _ en la variable?
Rob

@Rob He agregado el resultado basado en su pregunta; funciona como se esperaba, porque no toco los guiones bajos.
Ja͢ck

Nota: Esta es una solución editada que luego copió mi código y mi idea (ver registro de cambios). Debería ser eliminado por los moderadores.
Rok Kralj

Aparentemente, fue lo suficientemente bueno para que tomaras la bin2hex()idea de la mía, así que, ¿podemos dejar esta pelea sin sentido?
Ja͢ck

Bueno, lo cambié en lugar de la codificación base64. ¿Beneficio? Nada, salvo un poco de aceleración. ¿Por qué editar una solución perfecta para copiar la de otra persona?
Rok Kralj

5

Este enfoque es una versión alterada de Rok Kralj, pero con algunos ajustes para que funcione, para mejorar la eficiencia (evita devoluciones de llamada innecesarias, codificación y decodificación en claves no afectadas) y para manejar correctamente las claves de matriz.

Se encuentra disponible una esencia con pruebas y cualquier comentario o sugerencia es bienvenida aquí o allá.

public function fix(&$target, $source, $keep = false) {                        
    if (!$source) {                                                            
        return;                                                                
    }                                                                          
    $keys = array();                                                           

    $source = preg_replace_callback(                                           
        '/                                                                     
        # Match at start of string or &                                        
        (?:^|(?<=&))                                                           
        # Exclude cases where the period is in brackets, e.g. foo[bar.blarg]
        [^=&\[]*                                                               
        # Affected cases: periods and spaces                                   
        (?:\.|%20)                                                             
        # Keep matching until assignment, next variable, end of string or   
        # start of an array                                                    
        [^=&\[]*                                                               
        /x',                                                                   
        function ($key) use (&$keys) {                                         
            $keys[] = $key = base64_encode(urldecode($key[0]));                
            return urlencode($key);                                            
        },                                                                     
    $source                                                                    
    );                                                                         

    if (!$keep) {                                                              
        $target = array();                                                     
    }                                                                          

    parse_str($source, $data);                                                 
    foreach ($data as $key => $val) {                                          
        // Only unprocess encoded keys                                      
        if (!in_array($key, $keys)) {                                          
            $target[$key] = $val;                                              
            continue;                                                          
        }                                                                      

        $key = base64_decode($key);                                            
        $target[$key] = $val;                                                  

        if ($keep) {                                                           
            // Keep a copy in the underscore key version                       
            $key = preg_replace('/(\.| )/', '_', $key);                        
            $target[$key] = $val;                                              
        }                                                                      
    }                                                                          
}                                                                              

Boom esto funcionó perfectamente para mí, gracias El Yobo / Rok. Utilizándolo en un proyecto CodeIgniter 2.1.3.
xref

Notaría que si aparecen valores que no tienen% 20 entidades ya en su lugar, como 'Alguna clave = Algún valor', entonces la salida de esta función es 'Algun_clave = Algún valor', ¿tal vez la expresión regular podría modificarse?
xref

La expresión regular podría ajustarse para capturar espacios codificados sin URL ... pero si su fuente no está codificada en URL, entonces probablemente habrá otros problemas, ya que el manejo siempre decodifica y codifica cadenas, entonces la parse_strllamada volverá a codificar url. ¿Qué estás intentando analizar que aún no está codificado?
El Yobo

Gracias por la atribución. Sin embargo, podría advertirle que su código podría funcionar peor, porque los POST suelen tener unos pocos cientos de bytes. Prefiero la sencillez aquí.
Rok Kralj

1
¿Obtuviste esos puntos de referencia en alguna parte? Me interesa ver en qué escenarios es más lento, ya que todo lo que probé osciló entre la misma velocidad que la suya y el doble. Sospecho que la diferencia está en el tipo de cosas en las que se probó :) Puedes agregar fácilmente algunas verificaciones de tiempo a mi esencia para ver cómo va, ¿por qué no comparar el tuyo con la misma entrada y publicar resultados y tiempos?
El Yobo

4

La razón por la que esto sucede es debido a la antigua funcionalidad register_globals de PHP. Los . El carácter no es un carácter válido en un nombre de variable, por lo que PHP lo convierte en un guión bajo para asegurarse de que haya compatibilidad.

En resumen, no es una buena práctica hacer puntos en las variables de URL.


1
Tampoco es una buena idea tener register_globals activado. De hecho, debería estar apagado ahora mismo si es posible.
Amanecer

1
register_globals está de hecho desactivado, como es el predeterminado en PHP5. > El. El carácter no es un carácter válido en un nombre de variable Desafortunadamente no estoy buscando usar esto como un nombre de variable (lo mantengo como una clave en el diccionario $ _GET), por lo que esta 'consideración' en PHP no agrega valor :-( Ah, bueno ...

No importa si register_globals está activado o desactivado. PHP todavía realiza los reemplazos.
Jeremy Privett

3

Si busca alguna forma de hacer que PHP deje de reemplazar literalmente '.' caracteres en matrices $ _GET o $ _POST, entonces una de esas formas es modificar la fuente de PHP (y en este caso es relativamente sencillo).

ADVERTENCIA: ¡La modificación de la fuente PHP C es una opción avanzada!

También vea este informe de error de PHP que sugiere la misma modificación.

Para explorar, necesitará:

  • descargar el código fuente C de PHP
  • desactivar el .cheque de reemplazo
  • ./configurar , crear e implementar su compilación personalizada de PHP

El cambio de fuente en sí es trivial e implica actualizar solo la mitad de una línea en main/php_variables.c:

Nota: en comparación con el original || *p == '.' se ha comentado


Salida de ejemplo:

dado un QUERY_STRING de a.a[]=bb&a.a[]=BB&c%20c=dd, la ejecución <?php print_r($_GET);ahora produce:

Formación
(
    [aa] => Matriz
        (
            [0] => bb
            [1] => BB
        )

    [c_c] => dd
)

Notas:

  • este parche solo aborda la pregunta original (detiene el reemplazo de puntos, no de espacios).
  • ejecutar en este parche será más rápido que las soluciones de nivel de script, pero esas respuestas .php puro siguen siendo generalmente preferibles (porque evitan cambiar PHP en sí).
  • en teoría, un enfoque de polyfill es posible aquí y podría combinar enfoques: probar el cambio de nivel C utilizando parse_str()y (si no está disponible) recurrir a métodos más lentos.

1
Sin embargo, nunca deberías hacerlo así, +1 por el esfuerzo.
Rok Kralj

2

Mi solución a este problema fue rápida y sucia, pero todavía me gusta. Simplemente quería publicar una lista de nombres de archivo que se verificaron en el formulario. Solía base64_encodecodificar los nombres de archivo dentro del marcado y luego simplemente los decodificaba base64_decodeantes de usarlos.


2

Después de ver la solución de Rok, se me ocurrió una versión que aborda las limitaciones en mi respuesta a continuación, crb arriba y también la solución de Rok. Vea mi versión mejorada .


La respuesta de @ crb anterior es un buen comienzo, pero hay un par de problemas.

  • Reprocesa todo, lo cual es excesivo; solo aquellos campos que tienen un "." en el nombre necesita ser reprocesado.
  • No puede manejar matrices de la misma manera que lo hace el procesamiento PHP nativo, por ejemplo, para claves como "foo.bar []".

La siguiente solución resuelve ambos problemas ahora (tenga en cuenta que se ha actualizado desde que se publicó originalmente). Esto es aproximadamente un 50% más rápido que mi respuesta anterior en mis pruebas, pero no manejará situaciones en las que los datos tienen la misma clave (o una clave que se extrae de la misma manera, por ejemplo, foo.bar y foo_bar se extraen como foo_bar).

<?php

public function fix2(&$target, $source, $keep = false) {                       
    if (!$source) {                                                            
        return;                                                                
    }                                                                          
    preg_match_all(                                                            
        '/                                                                     
        # Match at start of string or &                                        
        (?:^|(?<=&))                                                           
        # Exclude cases where the period is in brackets, e.g. foo[bar.blarg]
        [^=&\[]*                                                               
        # Affected cases: periods and spaces                                   
        (?:\.|%20)                                                             
        # Keep matching until assignment, next variable, end of string or   
        # start of an array                                                    
        [^=&\[]*                                                               
        /x',                                                                   
        $source,                                                               
        $matches                                                               
    );                                                                         

    foreach (current($matches) as $key) {                                      
        $key    = urldecode($key);                                             
        $badKey = preg_replace('/(\.| )/', '_', $key);                         

        if (isset($target[$badKey])) {                                         
            // Duplicate values may have already unset this                    
            $target[$key] = $target[$badKey];                                  

            if (!$keep) {                                                      
                unset($target[$badKey]);                                       
            }                                                                  
        }                                                                      
    }                                                                          
}                                                                              

-1. ¿Por qué? 1. El espacio %20también es un carácter especial que se convierte en subrayado. 2. Su código procesa previamente todos los datos, ya que preg_match_alltiene que escanear todo, aunque usted diga que no lo hace. 3. El código de falla en ejemplos como este: a.b[10]=11.
Rok Kralj

Tienes razón sobre el espacio, gracias. Mi explicación ya señala que mi enfoque no maneja matrices, por lo que no estoy muy seguro de por qué lo está señalando. preg_match_alltiene que "procesar" una cadena, no extraer y reprocesar todas las claves y valores no afectados, por lo que también está un poco desviado. Dicho esto, su enfoque parse_stringparece un enfoque interesante que, con un poco de ajuste, podría ser mejor :)
El Yobo

Dice que extrae solo las claves afectadas, pero en términos de complejidad computacional, no lo hace. Está diciendo que tuvo algún tipo de acceso aleatorio para recuperar solo las claves afectadas, pero incluso si no hay claves afectadas presentes, debe acceder a toda la memoria. Si usted tiene un puesto con 100 megas de datos, no importa lo que permite extraer, ambos enfoques son lineales, O(n). De hecho, está empeorando la complejidad al usar la in_array()función, como se señaló anteriormente.
Rok Kralj

Estoy mirando a través de los 100megs una vez, sin dividirlos (lo que inmediatamente duplica la memoria), luego dividiéndolos nuevamente (doblando nuevamente) como en el método de crb que estaba comparando esto también. La notación Big O no tiene en cuenta el uso de memoria en absoluto, y esta implementación no usain_array todos modos. Además, si desea ejecutar algunas pruebas, notará que lo anterior sigue siendo significativamente más rápido; no O (n) vs O (n ^ 2), pero un enfoque lineal aún puede ser más rápido que otro ... y este es;)
El Yobo

La otra gran ventaja que tiene este enfoque es que la ventaja de la velocidad es mayor cuando no hay trabajo por hacer, es decir, cuando no se han proporcionado puntos o espacios en las teclas; esto significa que tiene una sobrecarga mínima si lo coloca para procesar todas las solicitudes, porque casi no funciona (una expresión regular), en lugar de extraer y codificar todas las claves varias veces.
El Yobo

0

Bueno, la función que incluyo a continuación, "getRealPostArray ()", no es una solución bonita, pero maneja matrices y admite ambos nombres: "alpha_beta" y "alpha.beta":

  <input type='text' value='First-.' name='alpha.beta[a.b][]' /><br>
  <input type='text' value='Second-.' name='alpha.beta[a.b][]' /><br>
  <input type='text' value='First-_' name='alpha_beta[a.b][]' /><br>
  <input type='text' value='Second-_' name='alpha_beta[a.b][]' /><br>

mientras que var_dump ($ _ POST) produce:

  'alpha_beta' => 
    array (size=1)
      'a.b' => 
        array (size=4)
          0 => string 'First-.' (length=7)
          1 => string 'Second-.' (length=8)
          2 => string 'First-_' (length=7)
          3 => string 'Second-_' (length=8)

var_dump (getRealPostArray ()) produce:

  'alpha.beta' => 
    array (size=1)
      'a.b' => 
        array (size=2)
          0 => string 'First-.' (length=7)
          1 => string 'Second-.' (length=8)
  'alpha_beta' => 
    array (size=1)
      'a.b' => 
        array (size=2)
          0 => string 'First-_' (length=7)
          1 => string 'Second-_' (length=8)

La función, por lo que vale:

function getRealPostArray() {
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {#Nothing to do
      return null;
  }
  $neverANamePart = '~#~'; #Any arbitrary string never expected in a 'name'
  $postdata = file_get_contents("php://input");
  $post = [];
  $rebuiltpairs = [];
  $postraws = explode('&', $postdata);
  foreach ($postraws as $postraw) { #Each is a string like: 'xxxx=yyyy'
    $keyvalpair = explode('=',$postraw);
    if (empty($keyvalpair[1])) {
      $keyvalpair[1] = '';
    }
    $pos = strpos($keyvalpair[0],'%5B');
    if ($pos !== false) {
      $str1 = substr($keyvalpair[0], 0, $pos);
      $str2 = substr($keyvalpair[0], $pos);
      $str1 = str_replace('.',$neverANamePart,$str1);
      $keyvalpair[0] = $str1.$str2;
    } else {
      $keyvalpair[0] = str_replace('.',$neverANamePart,$keyvalpair[0]);
    }
    $rebuiltpair = implode('=',$keyvalpair);
    $rebuiltpairs[]=$rebuiltpair;
  }
  $rebuiltpostdata = implode('&',$rebuiltpairs);
  parse_str($rebuiltpostdata, $post);
  $fixedpost = [];
  foreach ($post as $key => $val) {
    $fixedpost[str_replace($neverANamePart,'.',$key)] = $val;
  }
  return $fixedpost;
}

0

Usando crb, quería recrear la $_POSTmatriz como un todo, aunque tenga en cuenta que aún tendrá que asegurarse de que está codificando y decodificando correctamente tanto en el cliente como en el servidor. Es importante comprender cuándo un personaje es verdaderamente inválido y realmente válido . Además la gente debe todavía y siempre escapar de los datos del cliente antes de usarlo con cualquier comando de la base de datos sin excepción .

<?php
unset($_POST);
$_POST = array();
$p0 = explode('&',file_get_contents('php://input'));
foreach ($p0 as $key => $value)
{
 $p1 = explode('=',$value);
 $_POST[$p1[0]] = $p1[1];
 //OR...
 //$_POST[urldecode($p1[0])] = urldecode($p1[1]);
}
print_r($_POST);
?>

Recomiendo usar esto solo para casos individuales, de repente, no estoy seguro de los puntos negativos de poner esto en la parte superior de su archivo de encabezado principal.


0

Mi solución actual (basada en respuestas al tema anterior):

function parseQueryString($data)
{
    $data = rawurldecode($data);   
    $pattern = '/(?:^|(?<=&))[^=&\[]*[^=&\[]*/';       
    $data = preg_replace_callback($pattern, function ($match){
        return bin2hex(urldecode($match[0]));
    }, $data);
    parse_str($data, $values);

    return array_combine(array_map('hex2bin', array_keys($values)), $values);
}

$_GET = parseQueryString($_SERVER['QUERY_STRING']);

agregue alguna explicación que sea útil para todos los que leerán su respuesta.
Prafulla Kumar Sahu
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.