recibir - PHP faltan algunos $_POST valores pero están presentes en la entrada php://
recibir variables get php (12)
Tengo un formulario html muy grande (que contiene una tabla con filas, que contiene varias entradas), que debo enviar al script PHP mediante solicitud POST. El problema es que algunos valores no aparecen y están ausentes en $ _POST superglobal de PHP.
Comprobé (usando la extensión Firebug) que el navegador realmente envió los valores al servidor.
$ _POST se llena, pero faltan algunos valores.
Verifiqué qué es la solicitud sin procesar usando:
$raw_post = file_get_contents(''php://input'');
y la cadena devuelta tiene los valores. Simplemente no se analizan en la matriz $ _POST. Lo extraño que noté es que parece que los valores de entrada php: // se cortan después de cierta longitud, y el resto de la cadena no llega a $ _POST.
Pensé en post_max_size y memory_limit y los establecí en valores grandes:
memory_limit = 256M
post_max_size = 150M
pero de acuerdo con la documentación de php $ _POST no debe contener ningún valor si la solicitud realizada es mayor que post_max_size.
Debido al gran tamaño de la forma y la solicitud, no puedo publicarlo aquí, pero puedo publicar el script php que utilicé para resolver el problema:
var_dump($file = file_get_contents(''php://input''));
var_dump($_POST);
//... then i parsed the $file
Versión del servidor: Apache / 2.2.9 (Debian)
Versión de PHP: PHP 5.3.2-0.dotdeb.2
¿Puede alguien explicar la razón de tal comportamiento extraño de PHP, y qué debería hacer (cambiar las configuraciones de php, código?) Para usar $ _POST array mientras proceso el formulario?
EDITAR: Para ser claros: no solo faltan los valores. $ _POST tampoco contiene estas claves.
ex fragmento de la publicación en bruto:
t_dodparam%5B198%5D=&t_dodparam2%5B198%5D=&t_kolejnosc%5B198%5D=199&n_indeks=201&n_wartosc=testtesttest
La clave ''t_dodparam'' está en la publicación y tiene la clave 198. Falta el resto de los parámetros (ex t_dodparam2 está en la publicación, pero no tiene la clave 198, y no existe la clave n_wartosc en $ _POST)
¿Qué hay de usar "parse_str" para convertir la cadena de consulta en estructuras php? Esta función es la inversa de http_build_query.
$b = array();
parse_str(file_get_contents("php://input"), $b);
Acabo de solucionar este problema añadiendo un valor a max_input_vars en mi archivo de configuración de PHP. De acuerdo con this fue presentado en 5.3.9, sin embargo, después de algunas actualizaciones de paquetes, experimenté el problema en 5.3.2.
El valor predeterminado para max_input_vars es 1000, que era demasiado pequeño para mi formulario.
Encontré esta respuesta a través de una búsqueda y siento que debería ofrecer un problema alternativo. En mi caso, mi publicación no era demasiado grande y, sin embargo, el valor que estaba enviando en el campo no aparecía en la matriz $ _POST. Al final resultó que, accidentalmente tenía otro campo más abajo en mi forma con el mismo nombre. Asi que:
<form>
<input type="text" name="field1">
<input type="text" name="field2">
<input type="text" name="field3">
<input type="text" name="field1">
<input type="submit">
</form>
Cuando la variable $_POST
se rellena con datos de ese formulario, el valor en su primer campo se sobrescribirá con el valor en ese último campo con el mismo nombre. Si se necesita el primer campo y usted completa un valor, pero el último campo no es obligatorio y se envía vacío, verá síntomas similares a esta pregunta porque el valor $ _POST [''campo1''] mostrará el valor de la última elemento en tu forma que está vacío.
TLDR:
¡Asegúrate de buscar nombres de campos duplicados en tu formulario!
Enfrenté el mismo problema y encontré una solución muy valiosa sin aumentar ningún límite o tamaño en .ini. Sabemos que max_input_vars = 1000 de forma predeterminada y esto es perfecto. Simplemente haga una cosa concatenar los valores de la matriz e intente calcular su número de variables por debajo de 1000. Cada nombre de variable cuenta uno, no sus valores. Por ejemplo:
<code>
$i = 10; //counts 1
$i = array(1,2,3,4,5); //counts 5
</code>
Puedes hacerlo:
<code>
$i = 1_2_3_4_5; // counts 1
</code>
Espero entender
Estoy publicando la función .ajax () de Jquery. Estaba intentando recuperar mis datos de $_POST
pero estaba incompleto. Luego encontré esta publicación que me puso en el camino correcto. Sin embargo, el método getRealPOST () descrito anteriormente no funcionaba para mí: no puede manejar muy bien matrices multidimensionales y anidadas. En cambio, utilicé el método parse_str()
PHP, que hizo el truco y fue un poco más limpio:
$rawdata = file_get_contents(''php://input'');
$urldecoded = urldecode($rawdata);
parse_str($urldecoded, $parsed);
$data = $parsed[''data''];
(En mi JS estoy publicando un objeto donde la carga está en la propiedad de data
. La tuya probablemente sea diferente).
También fui a mi php.ini y max_memory
y max_input_vars
, pero no pareció resolver mi problema. También pasé un tiempo persiguiendo a una red arenque porque estaba usando mi registro de errores para imprimir los datos sin procesar, y olvidé que error_log
tiene un límite en la cantidad de caracteres que se imprimirán a menos que recuerde aumentarlo.
De todos modos, espero que esto ayude a cualquiera que se encuentre luchando contra este problema.
Hay muchas cosas diferentes que podrían estar causando esto. Lo mejor es verificar su registro de errores. Muchas de las cosas que causan este síntoma colocarán mensajes en el registro de errores, pero no mostrarán errores en su aplicación PHP.
Algunas de las posibles causas:
Suhosin
Suhosin es una extensión para PHP diseñada para proteger servidores y usuarios de fallas conocidas y desconocidas en aplicaciones PHP y el núcleo de PHP. Una de las cosas que hace es limitar el tamaño de $ _POST, $ _GET, $ _REQUEST y $ _COOKIE. Si su problema es Suhosin, obtendrá un error en su registro, como
ALERTA - límite de variable POST configurado excedido - variable caída ''foo''
La solución es simple, solo aumente la cantidad máxima de variables permitidas en php.ini. Si no tienes una sección suhosin, solo crea una. Como tal:
[suhosin]
suhosin.request.max_vars = 1000 # Default is 200
suhosin.post.max_vars = 1000 # Default is 200
Hay otras configuraciones suhosin que pueden causar esto, pero estos son los candidatos más probables.
Nombres de campo de formulario inválidos
En los viejos tiempos, PHP tenía una configuración llamada register_globals (ahora privada) que convertía automáticamente las variables GET y POST en variables de PHP. Entonces, si su formulario tiene los campos ''foo'' y ''bar'', cuando se envíe ese formulario las variables $ foo y $ bar se crearán automáticamente. Sin embargo, hay varios caracteres que no son válidos para usar en nombres de variables de PHP (espacio, punto, corchete abierto y otros). Dependiendo de qué caracteres haya utilizado, la variable puede tener los caracteres no válidos eliminados, perder su valor o ser desactivada. A pesar del hecho de que register_globals ya no se usa, PHP sigue eliminando estos caracteres al compilar $ _POST, $ _GET, $ _REQUEST y $ _COOKIE. Si no puede corregir los valores de los campos del formulario, puede intentar algo como:
<?php
/**
* Converts raw POST data into an array.
*
* Does not work for hierarchical POST data.
*
* @return array
*/
function real_post() {
static $post;
if (!isset($post)) {
$pairs = explode("&", file_get_contents("php://input"));
$post = array();
foreach ($pairs as $pair) {
$x = explode("=", $pair);
$post[rawurldecode($x[0])] = rawurldecode($x[1]);
}
}
return $post;
}
?>
Me encontré con esta publicación (ciertamente antigua) mientras trataba de encontrar una solución para el error de las teclas JavaScript Object, incluidos los corchetes en sus nombres, y PHP se confundía y actuaba como si nunca hubiera escuchado sobre la anidación. @Dalin tiene una buena respuesta básica, pero no crea una matriz anidada, ni convierte tipos de valor a boolean / number; de ahí que mi versión ( get_real_post() también esté en GitHub).
A pesar del nombre, esto debería funcionar de forma idéntica para _GET (es decir, cualquier cosa que php://input
capture).
/**
* Gets the _POST data with correct handling of nested brackets:
* "path[to][data[nested]]=value"
* "path"
* -> "to"
* -> "data[nested]" = value
* @return array
*/
function get_real_post() {
function set_nested_value(&$arr, &$keys, &$value) {
$key = array_shift($keys);
if (count($keys)) {
// Got deeper to go
if (!array_key_exists($key, $arr)) {
// Make sure we can get deeper if we''ve not hit this key before
$arr[$key] = array();
} elseif (!is_array($arr[$key])) {
// This should never be relevant for well formed input data
throw new Exception("Setting a value and an array with the same key: $key");
}
set_nested_value($arr[$key], $keys, $value);
} elseif (empty($key)) {
// Setting an Array
$arr[] = $value;
} else {
// Setting an Object
$arr[$key] = $value;
}
}
$input = array();
$parts = array();
$pairs = explode("&", file_get_contents("php://input"));
foreach ($pairs as $pair) {
$key_value = explode("=", $pair, 2);
preg_match_all("/([a-zA-Z0-9]*)(?:/[([^/[/]]*(?:(?R)[^/[/]]*)*)/])?/", urldecode($key_value[0]), $parts);
$keys = array($parts[1][0]);
if (!empty($parts[2][0])) {
array_pop($parts[2]); // Remove the blank one on the end
$keys = array_merge($keys, $parts[2]);
}
$value = urldecode($key_value[1]);
if ($value == "true") {
$value = true;
} else if ($value == "false") {
$value = false;
} else if (is_numeric($value)) {
if (strpos($value, ".") !== false) {
$num = floatval($value);
} else {
$num = intval($value);
}
if (strval($num) === $value) {
$value = $num;
}
}
set_nested_value($input, $keys, $value);
}
return $input;
}
Me enfrenté al mismo problema. Mi formulario creaba los elementos de entrada en un bucle. Se publicaron hasta 1000 elementos de entrada y print_r($_POST);
mostró todos los valores publicados.
Cuando los elementos de entrada en el formulario se numeraron por encima de 1000, print_r($_POST)
simplemente desapareció. Como si el formulario no se publicara en absoluto. Llegué a tu página de .com por búsqueda de google.
Sí, aumentar post_max_size
, post_max_size
, etc. no resolvió nada. Tengo experiencia práctica en que aumentar el memory_limit
más allá de 128M
puede ser peligroso. Una vez que nuestro servidor de alojamiento en vivo Apache se colgó. Yo era el experimentador :-)
max_input_vars
fue el único factor limitante.
echo ini_get(''max_input_vars'');
mostró que era 1000 por defecto. Extrañamente max_input_vars
estuvo ausente en php.ini . De todos modos, agregué
max_input_vars=10000
en mi php.ini y reinicié Apache.
Ahora echo ini_get(''max_input_vars'');
mostró que había aumentado a 10000
y mis datos de gran formato podrían quedar atrapados después de la publicación. Problema resuelto.
Veo que max_input_vars es el tipo PHP_INI_PERDIR. Lo que significa que no puedo cambiar su valor para la página php individual donde necesito un valor más alto usando ini_set (''max_input_vars'', 10000);
PHP modifica los campos que contienen el espacio de los caracteres, el punto, el corchete abierto y otros para que sean compatibles con los register_globals obsoletos
Puede encontrar muchas soluciones en los comentarios aquí: PHP: variables de fuentes externas
Para Exampe (comentario de POSTer):
<?php
//Function to fix up PHP''s messing up POST input containing dots, etc.
function getRealPOST() {
$pairs = explode("&", file_get_contents("php://input"));
$vars = array();
foreach ($pairs as $pair) {
$nv = explode("=", $pair);
$name = urldecode($nv[0]);
$value = urldecode($nv[1]);
$vars[$name] = $value;
}
return $vars;
}
?>
Para referencia futura: en una caja de Ubuntu, he estado luchando con este problema desde hace mucho tiempo y solía adoptar una solución similar a la descrita anteriormente para salvar el día. Seguí el problema en mi php.ini y finalmente lo encontré en línea con max_input_nesting_level = 0 Comenté la línea anterior, reinicié Apache y todo está arreglado.
Tuve el mismo problema y resultó que estaba usando AJAX para modificar dinámicamente el campo de entrada en función de otras entradas en el formulario. La función ajax recreó la entrada y no incluyó un nombre de entrada.
Use htmlspecialchars
con su $ _POST. Por ejemplo:
$day1=htmlspecialchars($_POST["day"]);
Espero que esto funcione.