2012-01-20 10 views
167

presento como POST a una página php lo siguiente:¿Cómo obtener el cuerpo de un POST en php?

{a:1} 

Este es el cuerpo de la solicitud (una solicitud POST).
En php, ¿qué debo hacer para extraer ese valor?

var_dump($_POST); 

no es la solución, no funciona.

+9

Esta es una pregunta útil para las personas que buscan crear APIs REST. La mayoría no sabe cómo acceder a los datos de entrada sin procesar enviados a sus scripts, ya que no está disponible a través del superglobal '$ _POST'. Esto también es (especialmente) cierto en el caso de solicitudes PUT, ya que PHP no tiene superglobal correspondiente. – rdlowrey

+4

Posible duplicado de [¿Cómo obtener el contenido de solicitud (cuerpo) en PHP?] (Https://stackoverflow.com/questions/7187631/how-to-get-request-content-body-in-php) – YakovL

Respuesta

373

Para acceder al cuerpo de la entidad de una petición POST o PUT (o cualquier otro método HTTP):

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

Además, la constante STDIN es una secuencia ya abierto a php://input, por lo que se puede hacer alternativamente:

$entityBody = stream_get_contents(STDIN); 

Desde el PHP manual entry on I/O streamsdocs:

php: // input es una secuencia de solo lectura que le permite leer datos brutos desde el cuerpo de la solicitud. En el caso de solicitudes POST, es preferible para usar php: // entrada en lugar de $HTTP_RAW_POST_DATA, ya que no depende de las directivas especiales php.ini. Además, para aquellos casos en los que $HTTP_RAW_POST_DATA no está poblado por defecto, es potencialmente una alternativa menos intensiva de memoria a que la activación de always_populate_raw_post_data. php: // input no está disponible con enctype = "multipart/form-data".

Específicamente usted querrá tener en cuenta que la corriente php://input, independientemente de cómo se accede a él en una SAPI web, no es reubicable. Esto significa que solo se puede leer una vez. Si está trabajando en un entorno en el que se cargan rutinariamente cuerpos de entidad HTTP grandes, es posible que desee mantener la entrada en su formato de secuencia (en lugar de almacenarla como el primer ejemplo anterior).

Para mantener el algo recurso de secuencia de este tipo pueden ser útiles:

<?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 gestionar el consumo de memoria, ya que se forma transparente cambiar a sistema de ficheros de almacenamiento después de una cierta cantidad de datos se almacenan (2M por defecto) Este tamaño se puede manipular en el archivo php.ini o al agregar /maxmemory:NN, donde NN es la cantidad máxima de datos que se debe conservar en la memoria antes de usar un archivo temporal, en bytes.

Por supuesto, a menos que tenga una muy buena razón para buscar en el flujo de entrada, no debería necesitar esta funcionalidad en una aplicación web. Leer el cuerpo de la entidad de solicitud de HTTP una vez es suficiente, por lo general, no deje que los clientes esperen todo el día mientras su aplicación averigua qué hacer.

Tenga en cuenta que la entrada php: // no está disponible para las solicitudes que especifican un encabezado Content-Type: multipart/form-data (enctype="multipart/form-data" en formularios HTML). Esto resulta de PHP que ya ha analizado los datos del formulario en el superglobal $_POST.

+8

Tenga en cuenta que afaics, el flujo de STDIN no está disponible en sistemas que ejecutan PHP usando CGI, es decir, a través de mod_fcgid o mod_fastcgi, etc. – scy

+0

pero, estoy pasando variable (como datos de formulario) con la solicitud, ¿cómo puedo acceder al valor especificado, estoy pasando grant_type = contraseña y nombre de usuario = usuario & contraseña = pasar como cuerpo de datos de formulario con la solicitud, ¿cómo obtendré grant_type de "$ entityBody" –

+0

según mi prueba, este 'php: // input' está vacío para' application/x-www-form -contenido de tipo'urlencoded' también (además de 'multipart/form-data') – YakovL

2
+5

El método preferido para acceder a los datos de POST sin formato es' php: // input'. '$ HTTP_RAW_POST_DATA' no está disponible con' enctype = "multipart/form-data" '. – nullability

+19

Esta característica fue DEPURADA en PHP 5.6.0, y RETIRADA a partir de PHP 7.0.0. – Charles

2

Si ha instalado la extensión PECL HTTP, puede hacer uso de la función http_get_request_body() para obtener datos del cuerpo como una cadena.

4

Una posible razón para que un vacío $_POST es que la petición no es POST, o no más POST ... Puede haber comenzado como correos, pero se encontró con una redirección 301 o 302 alguna parte, que se requiere para cambiar a GET !

Inspeccione $_SERVER['REQUEST_METHOD'] para comprobar si este es el caso.

+1

Esta pregunta fue formulada en el contexto del desarrollo de una plataforma API de REST. –

+0

No estoy seguro de lo que quieres decir? Una API REST también podría encontrar redirecciones en su camino, ese es el problema que tenía. – Legolas

+0

Quise decir cuando hice la pregunta, no estaba tratando de resolver un error, sino más bien tratando de descubrir cómo desarrollarlo. –

0

Si tiene instalada la extensión pecl/http, también se puede utilizar esto:

$request = new http\Env\Request(); 
$request->getBody(); 
Cuestiones relacionadas