Presento como POST a una página php lo siguiente:
{a:1}
Este es el cuerpo de la solicitud (una solicitud POST).
En php, ¿qué tengo que hacer para extraer ese valor?
var_dump($_POST);
No es la solución, no funciona.
Presento como POST a una página php lo siguiente:
{a:1}
Este es el cuerpo de la solicitud (una solicitud POST).
En php, ¿qué tengo que hacer para extraer ese valor?
var_dump($_POST);
No es la solución, no funciona.
Respuestas:
Para acceder al cuerpo de la entidad de una solicitud POST o PUT (o cualquier otro método HTTP):
$entityBody = file_get_contents('php://input');
Además, la STDIN
constante es una secuencia ya abierta php://input
, por lo que puede hacer alternativamente:
$entityBody = stream_get_contents(STDIN);
De la entrada manual de PHP en documentos de flujos de E / S :
php: // input es una secuencia de solo lectura que le permite leer datos sin procesar del cuerpo de la solicitud. En el caso de solicitudes POST, es preferible usar php: // input en lugar de,
$HTTP_RAW_POST_DATA
ya que no depende de directivas especiales php.ini. Además, para aquellos casos en los$HTTP_RAW_POST_DATA
que no se rellena de manera predeterminada, es una alternativa potencialmente menos intensiva en memoria para activar always_populate_raw_post_data. php: // input no está disponible con enctype = "multipart / form-data".
Específicamente, querrá tener en cuenta que la php://input
transmisión, independientemente de cómo acceda a ella en un SAPI web, no es buscable . Esto significa que solo se puede leer una vez. Si está trabajando en un entorno donde se cargan rutinariamente grandes cuerpos de entidades HTTP, es posible que desee mantener la entrada en su forma de flujo (en lugar de almacenarla en el búfer como en el primer ejemplo anterior).
Para mantener el recurso continuo, algo como esto puede ser útil:
<?php
function detectRequestBody() {
$rawInput = fopen('php://input', 'r');
$tempStream = fopen('php://temp', 'r+');
stream_copy_to_stream($rawInput, $tempStream);
rewind($tempStream);
return $tempStream;
}
php://temp
le permite administrar el consumo de memoria porque cambiará de forma transparente al almacenamiento del sistema de archivos después de que se almacene una cierta cantidad de datos (2M por defecto). Este tamaño se puede manipular en el archivo php.ini o agregando /maxmemory:NN
, donde NN
está la cantidad máxima de datos para guardar en la memoria antes de usar un archivo temporal, en bytes.
Por supuesto, a menos que tenga una buena razón para buscar en la secuencia de entrada, no debería necesitar esta funcionalidad en una aplicación web. Por lo general, leer el cuerpo de la entidad de solicitud HTTP una vez es suficiente: no haga que los clientes esperen todo el día mientras su aplicación determina qué hacer.
Tenga en cuenta que php: // input no está disponible para solicitudes que especifican un Content-Type: multipart/form-data
encabezado ( enctype="multipart/form-data"
en formularios HTML). Esto resulta de que PHP ya ha analizado los datos del formulario en el $_POST
superglobal.
php://input
está vacío para application/x-www-form-urlencoded
el tipo de contenido (además multipart/form-data
)
php://input
está. Entonces, mientras que las configuraciones CGI (rápidas) stream_get_contents(STDIN)
no funcionen, lo file_get_contents("php://input")
harán.
valor de retorno en la matriz
$data = json_decode(file_get_contents('php://input'), true);
$data
matriz asociativa para verificar si cada valor está codificado de la manera deseada. La forma de ver las cosas de "flujo a tipo de datos" puede ser simplista, pero puede no ser tan eficiente como tratar con la codificación en el "formulario de flujo" usando un filtro de flujo. Si no está manejando problemas de codificación y simplemente desinfectando y validando, se está perdiendo un paso.
Una posible razón para un vacío $_POST
es que la solicitud ya no es POST
, o POST
ya no ... Puede haber comenzado como una publicación, pero se encontró 301
o se 302
redirigió en algún lugar, ¡que se cambió a GET
!
Inspeccione $_SERVER['REQUEST_METHOD']
para verificar si este es el caso.
Vea https://stackoverflow.com/a/19422232/109787 para una buena discusión de por qué esto no debería suceder, pero aún así sucede.
POST
pero después de inspeccionar estaba demostrando que sí GET
. Una vez que agregué un /
al final de mi URL, comenzó a mostrar POST. ¡Extraño!
Comprueba la $HTTP_RAW_POST_DATA
variable
php://input
. $HTTP_RAW_POST_DATA
no está disponible con enctype="multipart/form-data"
.
Si ha instalado la extensión HTTP PECL, puede hacer uso de la http_get_request_body()
función para obtener datos del cuerpo como una cadena.
Si tiene instalada la extensión pecl / http , también puede usar esto:
$request = new http\Env\Request();
$request->getBody();
function getPost()
{
if(!empty($_POST))
{
// when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request
// NOTE: if this is the case and $_POST is empty, check the variables_order in php.ini! - it must contain the letter P
return $_POST;
}
// when using application/json as the HTTP Content-Type in the request
$post = json_decode(file_get_contents('php://input'), true);
if(json_last_error() == JSON_ERROR_NONE)
{
return $post;
}
return [];
}
print_r(getPost());
json_last_error() == JSON_ERROR_NONE
es así false
, se deba devolver una matriz vacía. ¿Qué pasa si alguien ha enviado XML o YAML? Agregue una prueba para Content-Type y vaya desde allí.
$_SERVER
superglobal para valores útiles para verificar.
http_get_request_body()
se hizo explícitamente para obtener el cuerpo PUT
y las POST
solicitudes según la documentación http://php.net/manual/fa/function.http-get-request-body.php
$_POST
superglobal. Esto también es (especialmente) cierto en el caso de solicitudes PUT, ya que PHP no tiene un superglobal correspondiente.