Get "Content-Type" header of request in PHP

96,597

Solution 1

Normal (GET) requests do not have a Content-Type header. For POST requests it would appear as $_SERVER["CONTENT_TYPE"], with a value like multipart/form-data or application/x-www-form-urlencoded.

This is mandated by the CGI/1.1 specification: http://www.ietf.org/rfc/rfc3875.

Solution 2

You'll need to manually instruct Apache to supply the Content-Type header (plus any other headers you want).

Pop something like this in your .htaccess file or virtual host:

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

And voila, you just synthesised your very own $_SERVER['HTTP_CONTENT_TYPE']!

Edit:

I assume you're running PHP as CGI with Apache so you can use verbs other than GET and POST, as most rest services do. If you're using another web server or largely unheard-of PHP SAPI, you'll need to use a similar trick; PHP as CGI simply doesn't have access to request headers outside the contents of $_SERVER, no matter what other mechanisms you use - $_ENV, apache_request_headers(), even the classes in the php_http extension will all be empty.

Solution 3

You can also get the content type (like "text/html") with this :

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

or

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

Update

Like Benjamin said, apache_request_headers is available with FastCGI from 5.4.0 and from internal PHP server since 5.5.7.

Share:
96,597
CodeZombie
Author by

CodeZombie

Passionate software developer. Enjoys to help other developers and contribute to the software development community. Happy that this page proves so helpful every day!

Updated on September 01, 2020

Comments

  • CodeZombie
    CodeZombie over 3 years

    I'm implementing a REST service in PHP. This service should be able to support multiple input and output formats (JSON, XML). For that reason I want to check the request headers "Accept" and "Content-Type" for the type of content sent and requested by the client.

    Accessing the "Accept" header is a simple as using $_SERVER['HTTP_ACCEPT']. But accessing the "Content-Type" header seems to be a difficult task. I searched the PHP documentation and the web, but the only solution offered was the use of the PHP function apache_request_headers() which is only supported when PHP is installed as an Apache module, which is not true in my case.

    So my question now: How can I access the header "Content-Type" of a request?

    • Admin
      Admin over 11 years
      Remember that $_SERVER["CONTENT_TYPE"] is not always available.
  • CodeZombie
    CodeZombie about 13 years
    Thanks, that did it! I'm impressed :-)
  • Neil E. Pearson
    Neil E. Pearson about 13 years
    Age-old problem with REST services on PHP/Apache rigs. I make a point of distributing the vhost with the application because they usually get pretty hefty. Glad it worked :)
  • CodeZombie
    CodeZombie over 11 years
    Thanks for the info. From the documentation: "These functions are only available when running PHP as an Apache module.". As far as I know PHP is often run using FastCGI. This is exactly the case in my scenario. I personally prefer $_SERVER["CONTENT_TYPE"], it looks much cleaner.
  • Ben Sinclair
    Ben Sinclair about 10 years
    @NeilE.Pearson Is there a way to allow charset in the header? I'm having problems with it accepting it.
  • Neil E. Pearson
    Neil E. Pearson about 10 years
    @BenSinclair as your question has been removed I'll assume an answer is no longer required ;)
  • Jake A. Smith
    Jake A. Smith almost 10 years
    There is a documented bug report for the built in PHP server. It should return CONTENT_TYPE but instead returns HTTP_CONTENT_TYPE. Hopefully its fixed in the near future. bugs.php.net/bug.php?id=66606&thanks=6
  • BenMorel
    BenMorel almost 10 years
    Note that apache_request_headers() is available under FastCGI from PHP 5.4.0
  • Vicary
    Vicary almost 9 years
    This does not require mod_rewrite SetEnvIfNoCase ^Content-Type "(.+)" CONTENT_TYPE=$1
  • ClearCrescendo
    ClearCrescendo over 8 years
    @BenSinclair That makes sense. I believe the media type in the response Content-Type: has the ;charset=UTF-8 appended but the form media type in the request does not. This is consistent with RFC6749 and the sad lack of UTF-8 specification for "application/x-www-form-urlencoded" is discussed in [tools.ietf.org/html/rfc6749#appendix-B](Appendix B)
  • Cagy79
    Cagy79 over 5 years
    This should be the selected answer!
  • tobyink
    tobyink over 4 years
    Although unusual, a GET request can have a Content-Type header and can include a request body.