2012-03-13 26 views
12

Actualmente estoy desarrollando una API Restful Json en PHP. Deseo enviar una solicitud de PUT al items/:id para actualizar un registro. Los datos se transferirán como application/json.PHP obtener el cuerpo de la solicitud PUT

Quiero llamar a la API con

curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid" 

En el lado del servidor, no soy capaz de recuperar el cuerpo de la petición. Intenté

file_get_contents("php://input"); 

pero esto devuelve una cadena vacía. También una combinación fopen()/fread() no funciona.

Al llamar a través de POST, todo funciona bien, puedo leer el json perfectamente en el lado del servidor. Pero la API ya no es relajante. ¿Alguien tiene una solución para esto? ¿Hay alguna otra forma de enviar y recibir a Json?

por cierto, estoy desarrollando la API con el Slim Framework.

+0

¿Has probado fopen ("php: // input", "r")? – sethcall

+0

Sí, no funcionó. – aladin

+1

Impresionante que estés usando slim. Espero que estés teniendo buenas experiencias. Realmente disfruté mi SLIM restful api creation – Jake

Respuesta

13

php://input es sólo la puede leer una vez para peticiones PUT:

Nota: Una corriente se abrió con php: // input sólo puede ser leído una vez; la secuencia no admite operaciones de búsqueda. Sin embargo, dependiendo de la implementación de SAPI, es posible abrir otra secuencia de entrada php: // y reiniciar la lectura. Esto solo es posible si los datos del cuerpo de la solicitud se han guardado. Normalmente, este es el caso de las solicitudes POST, pero no de otros métodos de solicitud, como PUT o PROPFIND.

http://php.net/manual/en/wrappers.php.php

El marco delgado ya lee los datos a petición. Tome los datos del objeto Request, en el que se ha leído.

+4

Muchas gracias, esto resolvió mi problema. Puedo obtener los datos brutos con $ app-> request-> getBody(); y luego haz un json_decode. No estaba al tanto de este método, ya que no está en la documentación. – aladin

+0

+1 este fue mi problema al usar el framework restTonic PHP. La variable de datos $ this-> request-> ya contenía el cuerpo PUT. Había leído la entrada php: // en mi controlador POST y no podía ver por qué el controlador PUT no podía usar el mismo método para manejar su cuerpo. – Neek

-1

Estaba leyendo la documentación del framework SLIM el otro día y decía que algunos navegadores tienen problemas con PUT y DELETE.

Extracto:

Por desgracia, los navegadores modernos no proporcionan soporte nativo para peticiones PUT. Para evitar esta limitación, asegurar el método de su formulario HTML es “post”, a continuación, añadir un parámetro de anulación método para su formulario HTML como esto:

<form action="/books/1" method="post"> 
    ... other form fields here... 
    <input type="hidden" name="_METHOD" value="PUT"/> 
    <input type="submit" value="Update Book"/> 
</form> 

Fuente: http://www.slimframework.com/documentation/stable

+0

El OP usa Curl para realizar la operación HTTP PUT. – GordonM

+0

Soy un poco nuevo en esto también, pero ¿acaba cURL de renunciar al problema del navegador? ¿Qué sucede si él está haciendo la solicitud curl a través de PHP y esa es la línea de comando equivalente? (No estoy diciendo que lo sea, estoy diciendo que el beneficio de línea de comando cURL aún existe) – Jake

+0

@Jake: sí, el uso de cURL omite el problema del navegador. Ningún navegador está involucrado en la forma en que llama al servicio. – Crontab

0

El ejemplo de la PHP manual utiliza fopen para acceder a la entrada php: // en modo lectura. ¿Has intentado hacerlo de esa manera?

EDITAR: El manual page for PHP:// dice algunas cosas que parecen sugerir que los datos PUT podrían no estar disponibles en algunos casos.

Nota: Una secuencia abierta con php: // entrada solo se puede leer una vez; la secuencia no admite operaciones de búsqueda. Sin embargo, dependiendo de la implementación de SAPI, es posible abrir otra secuencia php: // input y reiniciar la lectura. Esto solo es posible si se han guardado los datos del cuerpo de solicitud . Normalmente, este es el caso de las solicitudes POST, , pero no de otros métodos de solicitud, como PUT o PROPFIND.

No sé dónde te dejará esto con respecto al procesamiento PUT. Una página parece decir que es posible, la otra parece implicar que no funcionará en un conjunto incorrecto de circunstancias

1

En el lado del servidor, no puedo recuperar el cuerpo de la solicitud. Intenté file_get_contents ("php: // input");

Solo puede usar file_get_contents('php://input', 'r'); una vez por solicitud. Recuperar sus valores truncará también los valores, por lo que si lo llama dos veces, devolverá una cadena vacía.objeto de solicitud de Slim contiene los valores que necesita, por lo que:

<?php 
$app = new Slim(); 

$app->put('/items/someid', function() use ($app) { 
    echo $app->request()->put('example'); // should display "data". 
}); 
+1

Esto es cierto para los datos codificados en url, pero no para json sin formato. si envío la url de datos codificada, puedo acceder a ella a través del objeto de solicitud de Slim. no funciona para json duro. – aladin

+0

El problema persiste; solo puede leer php: // input * once *, y Slim ya lo ha hecho. Deberá usar el objeto de solicitud de Slim para obtener sus valores. –

+1

Aparentemente, Slim Framework lee el cuerpo de la solicitud en el momento de la construcción, por lo que la entrada php: // ya fue eliminada. ¡Gracias! – aladin

Cuestiones relacionadas