2012-01-17 61 views
149

Se me ha indicado usar el método php://input en lugar de $_POST al interactuar con las solicitudes Ajax de JQuery. Lo que no entiendo son los beneficios de usar este vs el método global de $_POST o $_GET.

Respuesta

299

La razón es que php://input devuelve todos los datos sin procesar después de los encabezados HTTP de la solicitud, independientemente del tipo de contenido.

El PHP superglobal $_POST, solamente se supone que datos envoltura que es ya sea

  • application/x-www-form-urlencoded (tipo de contenido estándar para simples form-mensajes) o
  • multipart/form-data-encoded (utilizado principalmente para la carga de archivos)

Esto se debe a que estos son los únicos tipos de contenido que must be supported by user agents. Por lo tanto, el servidor y PHP tradicionalmente no esperan recibir ningún otro tipo de contenido (lo que no significa que no puedan).

Por lo tanto, si simplemente fije una buena vieja HTML form, la solicitud se ve algo como esto:

POST /page.php HTTP/1.1 

key1=value1&key2=value2&key3=value3 

Pero si se está trabajando con el Ajax mucho, este probaby también incluye el intercambio de datos más complejos con los tipos (cadena, int, bool) y estructuras (matrices, objetos), por lo que en la mayoría de los casos JSON es la mejor opción. Sin embargo, una solicitud con una carga útil de JSON-sería algo como esto:

POST /page.php HTTP/1.1 

{"key1":"value1","key2":"value2","key3":"value3"} 

El contenido sería ahora application/json (o al menos ninguno de los anteriores mencionados), de modo de $_POST PHP -wrapper no sabe cómo manejar eso (todavía).

La información sigue allí, simplemente no puede acceder a ella a través del contenedor. Por lo tanto, debe buscarlo usted mismo en formato sin formato con file_get_contents('php://input') (as long as it's not multipart/form-data-encoded).

Esta es también la forma en que accederá a datos XML o cualquier otro tipo de contenido no estándar.

+20

+1 para "Esta es también la forma en que accedería a XML-data o cualquier otro tipo de contenido no estándar" – mandza

+0

@Quasdank Estoy enviando JSON desde la aplicación de Android al servidor php xampp en la nube (http://stackoverflow.com/ preguntas/36558261/json-enviado-desde-android-a-compute-engine-server-returns-null) pero no pude hacer que funcione cuando intenté file_get_contents ('php: // input'), que simplemente devuelve cadena (0). Esto solía funcionar en mi máquina local, pero no funciona cuando lo implementé en la nube. ¿Usted me podría ayudar por favor? –

26

php://input puede darle los bytes brutos de los datos. Esto es útil si los datos POST son una estructura codificada JSON, que a menudo es el caso de una solicitud AJAX POST.

Aquí es una función de hacer precisamente eso:

/** 
    * Returns the JSON encoded POST data, if any, as an object. 
    * 
    * @return Object|null 
    */ 
    private function retrieveJsonPostData() 
    { 
    // get the raw POST data 
    $rawData = file_get_contents("php://input"); 

    // this returns null if not valid json 
    return json_decode($rawData); 
    } 

La matriz $_POST es más útil cuando se está manejando los datos de valores clave de un formulario, presentado por un poste tradicional. Esto solo funciona si los datos POST están en un formato reconocido, generalmente application/x-www-form-urlencoded (ver http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 para más detalles).

+2

Vale la pena señalar que si pasa 'true' como el segundo parámetro a' json_decode', devolverá una matriz asociativa. – VSG24

18

Si los datos de la publicación están mal formados, $ _POST no contendrá nada. Sin embargo, php: // input tendrá la cadena mal formada.

Por ejemplo, hay algunas aplicaciones ajax, que no forman la secuencia correcta de clave-valor de publicación para cargar un archivo, y simplemente vuelcan todo el archivo como datos de entrada, sin nombres de variables ni nada. $ _POST estará vacío, $ _FILES vacíos también, y la entrada php: // contendrá el archivo exacto, escrito como una cadena.