php $ _POST matriz vacía al enviar el formulario

99

Tengo un CMS personalizado que he construido que funciona perfectamente en mi caja de desarrollo (Ubuntu / PHP5 + / MySQL5 +).

Acabo de moverlo al cuadro de producción para mi cliente y ahora todos los envíos de formularios se muestran como matrices $ _POST vacías.

Encontré un truco para verificar que los datos realmente se están pasando usando file_get_contents('php://input');y los datos se muestran bien allí: las matrices $_POST/ $_REQUESTsiempre están vacías.

También verifiqué que los encabezados de tipo de contenido también son correctos a través de firebug ( application/x-www-form-urlencoded; charset=utf-8).

Este problema ocurre independientemente de si un formulario se envía a través de AJAX o un formulario normal.

¡Cualquier ayuda es muy apreciada!


fuente
Verifique post_max_size: el valor debe establecerse como 8M, no 8MB. En el último caso, no verá ningún error, pero el tamaño de $ _POST se establecerá en 0
Sergei Karpov

Respuestas:

186

Sé que esta pregunta era sobre POST a través de un formulario, pero vine aquí en busca de respuestas para un problema similar al publicar con el tipo de contenido JSON. Encontré la respuesta y quise compartirla ya que me costó mucho tiempo.

Cuando se usa el tipo de contenido JSON, la matriz $ _POST no se completará (creo que solo con formularios de varias partes)

Esto es lo que funcionó para corregir el problema:

$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json, true);

¡Espero que esto ayude a alguien!

tiltem
fuente
Esta solución tiene sentido: arregló mi controlador de actualización por lotes :)
Martin Zeitler
2
Otra alternativa es cambiar el Content-Typeencabezado a application/x-www-form-urlencodedy luego serializar sus datos con $.param(dataObject). Eso debería ayudar.
ŁukaszBachman
1
@ ŁukaszBachman Cómo hacer que si DataObject es algo así como ........ title=something&body=anything. Quiero obtener el valle de título y cuerpo. $ dataobject ["título"] devuelve vacío. En mi caso, $ _POST está vacío. Y la única forma de obtenerlo usando file_get_contents ("php: // input") ... excepto que no está codificado en json.
Khurshid Alam
Esto es muy útil. Lo extraño es que no tengo problemas para enviar Json a mi máquina de desarrollo, pero sí a la de producción.
Simon H
86

Aquí hay otra posible causa: mi formulario se estaba enviando a dominio.com sin la WWW. y había configurado una redirección automática para agregar la "WWW". La matriz $ _POST se estaba vaciando en el proceso. Entonces, para solucionarlo, todo lo que tuve que hacer fue enviarlo a www.domain.com


fuente
24
Maldita sea, una reescritura de URL en mi htaccessfue la causa de que los POST no funcionaran. Estaba agregando automáticamente una barra a todas las URL, pero en el código como ACCIÓN estaba usando una URL sin una barra. Su respuesta ayudó, ya que nunca pensé en verificar el .htaccess. +1
binar
Tuve un reenvío de dominio (con enmascaramiento) usando Godaddy, y esta parece ser la fuente del problema. ¡Gracias!
Chris Prince
1
También tuve un problema similar, venía de mi .htaccessarchivo. Estaba quitando la .phpextensión de la URL y mi formulario se POSTdirigía a la URL con la extensión.
Emanuel Vintilă
25

Tuve un problema similar. Resultó ser una solución simple. En la forma que tenía

<formulario de acción = "directorio" método = "publicación">

donde directorio era el nombre de ... el directorio. Mi matriz POST estaba totalmente vacía. Cuando miré la URL en mi navegador, se mostró con una barra diagonal al final.

Agregar la barra diagonal al final de mi acción funcionó:

<formulario acción = "directorio /" método = "publicación">

¡Mi matriz $ _POST estaba llena de nuevo!

Randy Kilwag
fuente
1
Esto no debería ser una solución, por ejemplo en CakePHP, que tiene un buen sistema de enrutamiento, falló en esto (no me refiero a que Cake falló), tal vez el enfoque para este problema no sea el marco o los archivos .php, pero alguna configuración en Apache, me gustaría investigar más sobre este problema. Es bastante interesante.
James
En una nota similar, tuve el mismo problema que el OP, pero solo si la <form>etiqueta no tenía un nameatributo, y solo en IE.
jkt123
13

Asegúrese de que, en php.ini:

  • track_vars (solo está disponible en versiones muy antiguas de PHP) está configurado en On
  • variables_order contiene la letra P
  • post_max_size se establece en un valor razonable (por ejemplo, 8 MB)
  • (si usa parche de suhosin) suhosin.post.max_varsy suhosin.request.max_varsson lo suficientemente grandes.

Supongo que la segunda sugerencia mía resolverá tu problema.

MrMage
fuente
1
Gracias MrMage, agradezco su conocimiento y verificará la configuración de ini y le informará si eso funcionó. ¡Gracias!
1
La configuración "post_max_size" es mi éxito. Estaba cargando un archivo grande durante el envío del formulario y esta configuración contenía un valor menor. Así que obtengo una matriz de publicaciones vacía cuando envío el formulario.
shasi kanth
9

Descubrí que al publicar de HTTP a HTTPS, el $_POSTarchivo viene vacío. Esto sucedió mientras probaba el formulario, pero me tomó un tiempo hasta que me di cuenta de eso.

Marcos
fuente
5

Me encontré con un problema similar pero ligeramente diferente y me tomó 2 días entender el problema.

  • En mi caso, la matriz POST también estaba vacía.

  • Luego se verificó con file_get_contents ('php: // input'); y eso también estaba vacío.

Más tarde, descubrí que el navegador no estaba solicitando confirmación para volver a enviar los datos del formulario si actualizo la página cargada después del envío POST. Fue una página directamente refrescante. Pero cuando cambié la URL del formulario a una diferente, estaba pasando POST correctamente y solicité volver a enviar los datos cuando intenté actualizar la página.

Luego verifiqué qué está mal con la URL real. No hubo fallas con la URL, sin embargo, apuntaba a una carpeta sin index.php en la URL y estaba revisando POST en index.php.

Aquí dudé de que la redirección desde / hacia /index.php causa que los datos POST se pierdan y se pruebe la URL con la adición de index.php a la URL.

Eso funciono.

Publíquelo aquí para que alguien lo encuentre útil.

GUIR
fuente
1
Tuve el mismo problema, sin '/' al final de la url, no existe nada en $ _REQUEST, pero con '/' o '/index.php', todos los datos publicados existen en $ _REQUEST. ¡Podría ser mi configuración de nginx o alguna otra cosa!
MohaMad
4

No tengo una solución elegante en este momento, pero quería compartir mis hallazgos para referencia futura de otras personas que encuentren este problema. La fuente del problema fueron 2 valores php anulados en un archivo .htaccess. Simplemente había agregado estos 2 valores para aumentar el límite de carga de archivos desde los 8 MB predeterminados a algo más grande; observé que simplemente tener estos 2 valores en el archivo htaccess, ya sea más grande o más pequeño que el predeterminado, causaba el problema .

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

Agregué variables adicionales para, con suerte, elevar los límites para todas las vars suhosin.post.xxx/suhosin.upload.xxx, pero desafortunadamente, estas no tuvieron ningún efecto con este problema.

En resumen, no puedo explicar realmente el "por qué" aquí, pero he identificado la causa raíz. Mi sensación es que este es, en última instancia, un problema de suhosin / htaccess, pero desafortunadamente uno que no pude resolver aparte de eliminar los 2 valores anulados de php anteriores.

Espero que esto ayude a alguien en el futuro, ya que maté un puñado de horas resolviendo esto. Gracias a todos los que se tomaron el tiempo para ayudarme con esto (MrMage, Andrew)


fuente
Podría valer la pena hacer esta pregunta sobre Serverfault, particularmente si el problema radica en la configuración del servidor / htaccess.
David dice reinstalar a Monica
5
Si no me equivoco, el tamaño debe especificarse como 'xxM', y no como 'xxMB', así que me pregunto si eso podría tener algo que ver con eso ...
JC Inacio
4

Podría resolver el problema usando enctype = "application / x-www-form-urlencoded" ya que el valor predeterminado es "text / plain". Cuando marca $ DATA, el separador es un espacio para "texto / plano" y un carácter especial para "urlencoded".

Saludos cordiales Frank

RudeUrm
fuente
4

Tener la enable_post_data_readingconfiguración deshabilitada causará esto. Según la documentación:

enable_post_data_reading

Deshabilitar esta opción hace que $ _POST y $ _FILES no se llenen. La única forma de leer los datos posteriores será a través del contenedor de flujo de entrada php: //. Esto puede ser útil para solicitudes de proxy o para procesar los datos POST de manera eficiente en la memoria.

Luke A. Leber
fuente
4

Si está publicando en un archivo index.php en un directorio, por ejemplo /api/index.php, asegúrese de especificar en su formulario el directorio completo del archivo, por ejemplo

Esta

<form method="post" action="/api/index.php"> 
</form>

O

<form method="post" action="/api/"> 
</form>

trabajos.

Pero esto falla

<form method="post" action="/api"> 
</form>
Domingo G Akinsete
fuente
De hecho, tengo exactamente lo contrario. Descubrí que /my_urifuncionaría pero no /my_uri/.
Enlace
tenía el mismo problema. parece que apache o nginx agrega una redirección de / api a / api /
John Smith
4
<form action="test.php" method="post">
                        ^^^^^^^^^^^^^

De acuerdo, esto fue estúpido y me avergonzaré en público, pero hice un pequeño script de prueba para algo en PHP y cuando mi $_POST matriz estaba vacía, StackOverflow es el primer lugar donde busqué y no encontré la respuesta que necesitaba. .

Solo habia escrito

<form action="test.php">

y olvidé especificar el método como POST !

Estoy seguro de que alguien se reirá, pero si esto ayuda a alguien que hace lo mismo, ¡no me importa! ¡Todos lo hacemos de vez en cuando!

Iván
fuente
¡No puedo creer que también lo olvidé! Estoy probando un nuevo servidor y pensé que era algo debido a la configuración ... de todos modos, ¡gracias por el recordatorio!
Samuel Aiala Ferreira
4

En mi caso, al publicar de HTTP a HTTPS, $ _POST viene vacío. El problema era que el formulario tenía una acción como esta //example.com Cuando arreglé la URL en https://example.com , el problema desapareció.

Игорь Носков
fuente
1
Creo que es algo relacionado con cómo está configurado el servidor. Tengo los mismos problemas al usar GoDaddy como anfitrión. Esta solución no resolvió el problema.
acarlstein
Esta solución resolvió mi problema. Cada uno tenía una bonita cabeza.
gokaysatir
3

mismo problema aquí!

Estaba tratando de conectarme a mi código de servidor local a través de una solicitud de publicación en cartero, ¡y este problema me hizo perder mucho tiempo!

para cualquiera que use un proyecto local (por ejemplo, cartero): use su dirección IPv4 (escriba ipconfig en cmd) en lugar de la palabra clave "localhost". en mi caso:

antes de:

localhost/app/login

después:

192.168.1.101/app/login
Ali Shariati
fuente
Postman me ha dado algunos problemas con valores json raspados que tienen comillas o espacios. Espera un formato específico.
Tom Anderson
2

REFERENCIA: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

Método POST

Vamos a realizar algunas modificaciones para que se utilice el método POST al enviar la solicitud ...

var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);

//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}
http.send(params);

Algunos encabezados http deben configurarse junto con cualquier solicitud POST. Así que los ponemos en estas líneas ...

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

Con las líneas anteriores, básicamente estamos diciendo que el envío de datos tiene el formato de envío de un formulario. También damos la longitud de los parámetros que estamos enviando.

http.onreadystatechange = function() {//Call a function when the state changes.
  if(http.readyState == 4 && http.status == 200) {
    alert(http.responseText);
  }
}

Establecimos un controlador para el evento de cambio de 'estado listo'. Este es el mismo controlador que usamos para el método GET. Puede usar http.responseText aquí: insértelo en un div usando innerHTML (AHAH), eval it (JSON) o cualquier otra cosa.

http.send(params);

Finalmente, enviamos los parámetros con la solicitud. La URL proporcionada se carga solo después de llamar a esta línea. En el método GET, el parámetro será un valor nulo. Pero en el método POST, los datos a enviar se enviarán como argumento de la función de envío. La variable params se declaró en la segunda línea como lorem=ipsum&name=binny, por lo que enviamos dos parámetros, 'lorem' y 'name' con los valores 'ipsum' y 'binny' respectivamente.

Chandu
fuente
1

En mi caso, fue porque estaba usando jQuery para deshabilitar todas las entradas en la página justo antes de usar jQuery para enviar el formulario. Así que cambié mi "deshabilitar todas las entradas, incluso los tipos 'ocultos'":

$(":input").attr("disabled","disabled"); 

para "deshabilitar solo las entradas de tipo 'botón'":

$('input[type=button]').attr('disabled',true);

¡Esto fue para que el usuario no pudiera presionar accidentalmente el botón 'ir' dos veces y lavar nuestra base de datos! Parece que si coloca el atributo 'deshabilitado' en una entrada de formulario de tipo 'oculto', sus valores no se enviarán si se envía el formulario.

Josh P
fuente
1

Para mí, .htaccess estaba redirigiendo cuando mod_rewrite no estaba instalado. Instale mod_rewite y todo está bien.

Específicamente:

<IfModule !mod_rewrite.c>
  ErrorDocument 404 /index.php
</Ifmodule>

estaba ejecutando.

Martín Fisher
fuente
1

Pasé horas para solucionar un problema similar. El problema en mi caso fue el

max_input_vars = "1000"

de forma predeterminada, en php.ini. Tenía un formulario realmente enorme sin cargas. php.ini está configurado para upload_max_filesize = "100M" y post_max_size = "108M" y seguramente no fue el problema en mi caso. El comportamiento de PHP es el mismo para max_input_vars cuando excede 1000 variables en el formulario. Devuelve una matriz _POST vacía. Ojalá hubiera podido encontrar eso hace una hora y horas.

MyraGe
fuente
1

Sé que esto es antiguo, pero quería compartir mi solución.

En mi caso, el problema estaba en mi .htaccess, ya que agregué variables para aumentar el límite máximo de carga de PHP. Mi código era así:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

Más tarde, noté que los valores deberían ser xxM, no xxMB y cuando lo cambié a:

php_value post_max_size 50M
php_value upload_max_filesize 50M

ahora mi $ _POST devolvió los datos como antes. Espero que esto ayude a alguien en el futuro.

Walid Ajaj
fuente
0

Además de la publicación de MRMage:

Tuve que configurar esta variable para resolver el problema de que algunas $_POSTvariables (con una matriz grande> 1000 elementos) desaparecieron:

suhosin.request.max_vars = 2500

" request", no " post" fue la solución ...

Asentamiento Itzekocke
fuente
0

Quizás no sea la solución más conveniente, pero me di cuenta de que si configuro el actionatributo de formulario en el dominio raíz, se puede acceder a index.php y se obtienen las variables publicadas. Sin embargo, si configuro una URL reescrita como acción, no funciona.

Rápli András
fuente
0

Esto es algo similar a lo que dijo @icesar .

Pero estaba tratando de publicar cosas en mi api, ubicada en site/api/index.php, solo publicando en, site/apiya que se pasa a index.phpsí mismo. Sin embargo, esto aparentemente causó que algo se estropeara, ya que mi $_POSTse vació sobre la marcha. Simplemente publicando site/api/index.phpdirectamente en su lugar lo resolvió.

Victor Häggqvist
fuente
0

Mi problema fue que estaba usando la <base>etiqueta HTML para cambiar la URL base de mi sitio de prueba. Una vez que eliminé esa etiqueta del encabezado, los $_POSTdatos volvieron.

Ben
fuente
0

En mi caso (la página php en el servidor mutualisé de OVH) enctype="text/plain"no funciona ( $_POSTy el correspondiente $_REQUESTestá vacío), los otros ejemplos a continuación funcionan. '

<form action="?" method="post">
<!-- in this case, my google chrome 45.0.2454.101 uses -->
<!--     Content-Type:application/x-www-form-urlencoded -->
    <input name="say" value="Hi">
    <button>Send my greetings</button>
</form>

<form action="?" method="post" enctype="application/x-www-form-urlencoded">
    <input name="say" value="Hi">
    <button>Send my application/x-www-form-urlencoded greetings</button>
</form>

<form action="?" method="post"  enctype="multipart/form-data">
    <input name="say" value="Hi">
    <button>Send my multipart/form-data greetings</button>
</form>

<form action="?" method="post" enctype="text/plain"><!-- not working -->
    <input name="say" value="Hi">
    <button>Send my text/plain greetings</button>
</form>

'

Más aquí: method = "post" enctype = "text / plain" no son compatibles?

PaulH
fuente
0

Recibí el siguiente error de Mod Security:

Access denied with code 500 (phase 2). Pattern match "((select|grant|delete|insert|drop|alter|replace|truncate|update|create|rename|describe)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]+[[:space:]]+(from|into|table|database|index|view)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]|UNION SELECT.*\'.*\'.*,[0-9].*INTO.*FROM)" at REQUEST_BODY. [file "/usr/local/apache/conf/modsec2.user.conf"] [line "345"] [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]

Una vez que eliminé la configuración de seguridad de mi mod para probar, todo funcionó como se esperaba. Ahora solo necesito modificar mis reglas para mantenerme seguro pero lo suficientemente flexible para mis necesidades :)

Luke
fuente
0

Asegúrese de utilizar name = " your_variable_name " en la etiqueta de entrada.

Utilizo por error id = " your_variable_name ".

Pasé mucho tiempo para atrapar el error.

Frank Hsieh
fuente
0

Asegúrese de que la namepropiedad de cada campo esté definida.

Esto te crea un POST vacío en PHP

<input type="text" id="Phone">

Pero esto funcionará

<input type="text" name="Phone" id="Phone">
Miguel Montes de Oca
fuente
Creo que es algo relacionado con cómo está configurado el servidor. Tengo los mismos problemas al usar GoDaddy como anfitrión. Esta solución no resolvió el problema.
acarlstein
-1

De acuerdo, pensé que debería poner mi caso aquí ... Estaba obteniendo la matriz de publicaciones vacía en casos específicos ... El formulario funciona bien, pero algunas veces los usuarios se quejan de que presionan el botón enviar y no pasa nada ... Después de investigar un rato, descubrí que mi empresa de alojamiento tiene un módulo de seguridad que verifica las entradas de los usuarios y borra toda la matriz de publicaciones (no solo los datos maliciosos) si lo descubre. En mi ejemplo, un profesor de matemáticas intentaba introducir la ecuación: dy + dx + 0 = 0; y los datos se borraron por completo.

Para solucionar esto, solo le aconsejo que ingrese los datos en el área de texto como dy + dx + 0 = cero, y ahora funciona ... Esto puede ahorrarle a alguien algo de tiempo ...

Mahmoud Elgabry
fuente
5
Pedirle a los usuarios que hagan concesiones para el código defectuoso no es nada fácil.
Freeworlder
No es realmente un código defectuoso, pero podría considerar un nuevo proveedor de alojamiento. De forma alternativa, publique la entrada en un formato diferente, por ejemplo, codificación URL HTML.
Tom Anderson