Cómo obtener el cuerpo de un POST en php?


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.

 191
Author: rdlowrey, 2012-01-20

5 answers

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');

También, la constante STDIN es una corriente ya abierta a php://input, por lo que alternativamente puede hacer:

$entityBody = stream_get_contents(STDIN);

De la entrada manual de PHP en flujos de E/Sdocs:

php: / / input es un flujo de solo lectura que le permite leer datos sin procesar del cuerpo de solicitud. En el caso de solicitudes POST, es preferible utilizar php: / / input en lugar de $HTTP_RAW_POST_DATA ya que no depende de php especial.directivas ini. Además, para los casos en que $HTTP_RAW_POST_DATA no se rellena por defecto, es un potencial menos memoria intensiva alternativa a la activación always_populate_raw_post_data. php://input no está disponible con enctype= "multipart / form-data".

Específicamente, querrá tener en cuenta que el flujo php://input, independientemente de cómo acceda a él en un SAPI web, no es buscable. Esto significa que solo se puede leer una vez. Si está trabajando en un entorno en el que se cargan rutinariamente grandes entidades HTTP, es posible que desee mantener la entrada en su forma de flujo (en lugar de almacenarla en búfer como en el primer ejemplo anterior).

Para mantener el recurso de flujo 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 predeterminado). Este tamaño puede ser manipulado en php.archivo ini o anexando /maxmemory:NN, donde NN es la cantidad máxima de datos a guardar en memoria antes de usar un archivo temporal, en bytes.

Por supuesto, a menos que tenga una 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 HTTP una vez suele ser suficiente: no hagas esperar a los clientes todo el día mientras tu aplicación determina qué hacer.

Tenga en cuenta que php: / / input no está disponible para peticiones que especifiquen un encabezado Content-Type: multipart/form-data (enctype="multipart/form-data" en formularios HTML). Esto se debe a que PHP ya ha analizado los datos del formulario en el $_POST superglobal.

 415
Author: rdlowrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 23:54:30

Una posible razón para un $_POST vacío es que la solicitud ya no es POST, o ya no es POST... Puede haber comenzado como post, pero se encontró con un 301 o 302 redireccionamiento en algún lugar, que se requiere para cambiar a GET!

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

 4
Author: Legolas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-23 02:07:14

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.

 3
Author: shivanshu patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 05:19:40
 2
Author: linepogl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-20 18:13:05

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

$request = new http\Env\Request();
$request->getBody();
 0
Author: spinkus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-23 00:08:47