2011-04-01 21 views
39

Estoy implementando un servicio REST en PHP. Este servicio debería ser compatible con múltiples formatos de entrada y salida (JSON, XML). Por ese motivo, deseo verificar los encabezados de solicitud "Aceptar" y "Content-Type" para el tipo de contenido enviado y solicitado por el cliente.Obtener el encabezado de solicitud de "Content-Type" en PHP

Acceder al "Aceptar" encabezado es un simple como usar $_SERVER['HTTP_ACCEPT']. Pero acceder al encabezado "Content-Type" parece ser una tarea difícil. Busqué en la documentación PHP y en la web, pero la única solución ofrecida fue el uso de la función PHP apache_request_headers(), que solo se admite cuando PHP está instalado como un módulo Apache, lo que no es cierto en mi caso.

Así que mi pregunta ahora: ¿Cómo puedo acceder al encabezado "Content-Type" de una solicitud?

+0

Recuerde que '$ _SERVER [" CONTENT_TYPE "]' no siempre está disponible. –

Respuesta

47

Las solicitudes normales (GET) no tienen un encabezado Content-Type. Para solicitudes POST aparecerá como $_SERVER["CONTENT_TYPE"], con un valor como multipart/form-data o application/x-www-form-urlencoded.

Esto es obligatorio por la especificación CGI/1.1: http://www.ietf.org/rfc/rfc3875.

+6

Hay un informe de error documentado para el servidor PHP incorporado. Debería devolver 'CONTENT_TYPE' pero en su lugar devuelve' HTTP_CONTENT_TYPE'. Esperemos que esté arreglado en el futuro cercano. https://bugs.php.net/bug.php?id=66606&thanks=6 –

18

Deberá indicar manualmente a Apache que proporcione el encabezado Content-Type (más cualquier otro encabezado que desee).

Pop algo como esto en su archivo .htaccess o host virtual:

RewriteEngine on 
RewriteRule .* - [E=HTTP_CONTENT_TYPE:%{HTTP:Content-Type},L] 

y listo, solo sintetiza su propio $_SERVER['HTTP_CONTENT_TYPE']!

Editar:

Asumo que se está ejecutando PHP como CGI con Apache para que pueda utilizar verbos que no sean GET y POST, como la mayoría de los servicios de descanso hacen. Si está utilizando otro servidor web o PHP SAPI sin precedentes, deberá usar un truco similar; PHP como CGI simplemente no tiene acceso a los encabezados de solicitud fuera del contenido de $_SERVER, no importa qué otros mecanismos use: $_ENV, apache_request_headers(), incluso las clases en la extensión php_http estarán vacías.

+0

¡Gracias, eso fue todo!Estoy impresionado :-) – CodeZombie

+0

Problema ancestral con los servicios REST en equipos PHP/Apache. Hago un punto de distribuir el vhost con la aplicación porque generalmente se vuelven bastante fuertes. Me alegro de que funcionó :) –

+0

@ NeilE.Pearson ¿Hay alguna manera de permitir 'charset' en el encabezado? Estoy [teniendo problemas] (http://stackoverflow.com/questions/21720797/oauth-server-and-content-type-header) con la aceptación. –

4

También puede obtener el tipo de contenido (como "text/html") con esto:

echo split(',', getallheaders()['Accept'])[0]; 

o

echo get_headers('http://127.0.0.1', 1)["Content-Type"] 

actualización

dijo Al igual que Benjamin , apache_request_headers está disponible con FastCGI desde 5.4.0 y desde inte rnal servidor PHP desde 5.5.7.

+1

Gracias por la información. De la documentación: "Estas funciones solo están disponibles cuando se ejecuta PHP como módulo de Apache". Por lo que sé PHP se ejecuta a menudo usando FastCGI. Este es exactamente el caso en mi escenario. Personalmente prefiero '$ _SERVER [" CONTENT_TYPE "]', parece mucho más limpio. – CodeZombie

+2

Tenga en cuenta que 'apache_request_headers()' está disponible en FastCGI desde PHP 5.4.0 – Benjamin

+1

y desde el servidor interno de PHP desde 5.5.7. Respuesta actualizada! –

Cuestiones relacionadas