2009-09-01 10 views
28

De acuerdo con php manual y php: // entrada ni $HTTP_RAW_POST_DATA trabajar con multipart/form-data POST-requests.Obtener datos de entrada sin formato

"php: // entrada no está disponible con enctype="multipart/form-data"..: // input le permite leer los datos POST primas Es una alternativa intensiva de memoria a menos $HTTP_RAW_POST_DATA y no necesita ningún directivas especiales de php.ini PHP."

¿Cómo puedo obtener datos brutos para formularios multipart/form-data?

+0

Si es por el bien de contar bytes, no se puede combinar el recuento de $ HTTP_RAW_POST_DATA bytes con el número de bytes de cualquier $ _FILES? – karim79

+0

@ karim79, porque no lo es. – Pacerier

Respuesta

34

Respuesta directa: no se puede hacer eso. PHP insiste en analizarlo él mismo, siempre que vea el tipo de contenido multipart/form-data. Los datos brutos no estarán disponibles para usted. Tristemente. Pero puedes hackearlo.

Me tocó un problema similar, un socio estaba enviando datos formateados incorrectamente como multiparte/form-data, PHP no pudo analizarlo y no lo estaba distribuyendo para que yo pudiera analizarlo.

¿La solución? He añadido esto a mi configuración del Apache:

<Location "/backend/XXX.php"> 
    SetEnvIf Content-Type ^(multipart/form-data)(.*) NEW_CONTENT_TYPE=multipart/form-data-alternate$2 OLD_CONTENT_TYPE=$1$2 
    RequestHeader set Content-Type %{NEW_CONTENT_TYPE}e env=NEW_CONTENT_TYPE 
</Location> 

Esto cambiará el tipo de contenido de la solicitud entrante a XXX.php de multipart/form-data en multipart/form-data-alternativo, lo cual es suficiente para bloquear PHP de intentar analizarlo

Después de esto, finalmente puede leer toda la información sin procesar de la entrada php: // y analizarla usted mismo.

Es feo, pero no he encontrado una solución mejor o, de hecho, ninguna otra, sin pedirle al socio que la corrija.

¡NOTA! Cuando hagas lo que describí aquí, $ _FILES estará vacío.

+0

Si reemplazo el encabezado Content-type de esta manera, recupero el origen php en mi navegador. Parece que el motor de php no procesará esta solicitud. ¿Cuál es el truco? Utilicé reemplazos de encabezado diferentes, ninguno funcionó. –

+0

Parece que ** es posible ** hacer esto con ['enable_post_data_reading'] (http://stackoverflow.com/a/19710850/632951). – Pacerier

+0

@Pacerier - posible, mi respuesta fue escrita antes de php 5.4 –

5

No implementé esto por completo, pero parece que debería funcionar. En Apache conf:

SetEnvIf Content-Type ^(multipart/form-data)(.*) MULTIPART_CTYPE=$1$2 
RequestHeader set Content-Type application/x-httpd-php env=MULTIPART_CTYPE 
RequestHeader set X-Real-Content-Type %{MULTIPART_CTYPE}e env=MULTIPART_CTYPE 

Ajuste del Content-Type a application/x-httpd-php parece resolver el problema original de PHP analizar el cuerpo, y el problema Norbert Farkas reportado: "Apache devuelve el código fuente PHP". El cuerpo está entonces disponible en php://input, y el tipo de contenido real en el encabezado X-Real-Content-Type. (Ese encabezado puede no ser necesario para usted - la variable MULTIPART_CTYPE no parecía mostrarse en mi $_ENV, pero el nuevo encabezado sí lo hizo.) Todas las demás solicitudes se deben manejar de la forma habitual.

Gracias a Anti Veeranna para la mayor parte! :)

EDITAR: P.S. Obviamente es específico de Apache, pero en algunas de las otras configuraciones de PHP puede haber formas mucho más sencillas.

9

Puede establecer enable_post_data_reading = Off y PHP no interceptará los datos multipart/form-data.

Requiere: PHP 5.4

+1

Interesante. Especialmente cuando el Manual de PHP en otra parte insiste en que es imposible obtener el cuerpo sin procesar en el caso de 'multipart/form-data'. – Anshul

+0

@Anshul, ¿El manual aún dice eso? No hay una versión coherente del manual. Algunas páginas son de la versión X, mientras que otras están en la versión Z. – Pacerier

+0

@Pacerier, sigo creyendo que no es posible obtener los datos multipart/form raw. Todos los enlaces siguientes sugieren que: http://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data http://php.net/manual/en /ini.core.php#ini.enable-post-data-reading http://php.net/manual/en/wrappers.php.php http://php.net/manual/en/reserved.variables .httprawpostdata.php – Anshul

Cuestiones relacionadas