PHP 5.6 default_charset change may break HTML output


GamesGames

An important note for everyone who’s upgrading from PHP 5.4 and PHP 5.5, to PHP 5.6: the PHP default_charset in php.ini changed from “empty” to UTF-8, making UTF-8 the default charset in PHP. This may break HTML output if you try to set a different charset in your HTML head. It may also break functions like htmlentities() and htmlspecialchars. For example:

UTF-8 encoding breaks when upgrading PHP 5.6 to PHP 7.0, fix PHP with ini_set( 'default_charset', "" ); or in your php.ini with default_charset = "".

Breaking HTML output with PHP 5.6 default_charset changed to UTF-8

Suppose you have the following lines in PHP code (don’t ask me why you would want to do this…):

<html> 
<head> 
<meta http-equiv="content-type"
  content="text/html; charset=ISO-8859-1"> 
</head>
<body> 
<?php echo "éééééeeeeééé"; ?>
</body> 
</html>Code language: HTML, XML (xml)

The PHP default charset setting in PHP 5.4 and PHP 5.5 prints the expected string on the screen: éééééeeeeééé.

In PHP 5.6 however, the default_charset is set to UTF-8, changing PHP’s default charset, and PHP 5.6 will always print a Content-Type response header set to UTF-8:

Content-Type: text/html; charset=UTF-8Code language: HTTP (http)

The PHP default charset set to UTF-8 breaks HTML output and functions like htmlentities() / htmlspecialchars() (PHP bug #61354), because the HTML charset ISO-8859-1 is printed too (creating a double Content-Type response header):

GET -uUsSed http://www.example.com/echo.php
GET http://www.example.com/echo.php
User-Agent: lwp-request/2.07

GET http://www.example.com/echo.php --> 200 OK
Cache-Control: private
Date: Tue, 31 Mar 2015 12:03:50 GMT
Server: Microsoft-IIS/8.0
Content-Length: 141
Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=ISO-8859-1
Client-Date: Tue, 31 Mar 2015 12:03:50 GMT
Client-Peer: 77.94.251.244:80
Client-Response-Num: 1Code language: Bash (bash)

PHP.net writes:

If omitted, the default value of the encoding varies depending on the PHP version in use. In PHP 5.6 and later, the default_charset configuration option is used as the default value. PHP 5.4 and 5.5 will use UTF-8 as the default. Earlier versions of PHP use ISO-8859-1.

Although this argument is technically optional, you are highly encouraged to specify the correct value for your code if you are using PHP 5.5 or earlier, or if your default_charset configuration option may be set incorrectly for the given input.

PHP.net htmlspecialchars()

How to fix the HTML output in PHP 5.6 – and up (7.0, 7.1)

The most obvious solution to this problem is: don’t set a character set encoding in your HTML meta tag, e.g:

<meta http-equiv="content-type"
  content="text/html; charset=ISO-8859-1">Code language: HTML, XML (xml)

Other options to set a correct default character set (default_charset) are:

Create an user-defined php.ini to overrule default_charset directive

PHP supports user-defined php.ini files, in which you can overrule some php.ini settings. Neat! Upload your user-defined php.ini to your webroot containing the following line:

default_charset = ""Code language: Apache (apache)

This will tell PHP to not send a Content-Type response header set to UTF-8.

Overrule PHP’s default_charset with ini_set()

And last but not least, you can overrule this setting with PHP’s ini_set() function:

ini_set( 'default_charset', "" );Code language: PHP (php)
foto van Jan Reilink

About the author

Hi, my name is Jan. I am not a hacker, coder, developer or guru. I am merely a systems administrator, doing my daily SysOps/DevOps thing at cldin. With over 15 years of experience, my specialties include Windows Server, IIS, Linux (CentOS, Debian), security, PHP, websites & optimization.

0 0 votes
Article Rating
Subscribe
Notify of
12 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
2 years ago

Thanks!

Mihail
3 years ago

thank so much!

Boris
3 years ago

Great post thank so much!

Flaviu
4 years ago

Great! Thanks for the tip.

Terratroz
4 years ago

Thank you

Palle
5 years ago

Thanks but it should be:

ini_set(‘default_charset’, ”);
or
ini_set(‘default_charset’, ‘none’);

or you get an PHP Notice: Use of undefined constant default_charset – assumed ‘default_charset’

Anonymous
5 years ago

Thank you!!

Anonymous
5 years ago

In PHP 7.0.19, the empty value of the default_charset directive (default_charset = “”) causes an error HTTP 500 “Internal Server Error”.
You can solve this problem by setting the value to “none”. For example:
php_value default_charset = none
or
php_value default_charset = “none”
or
php_value default_charset = ‘none’

Abdulla Saeed
Reply to  Anonymous
2 years ago

Thanks you ……
I was searching about 2 days
I used default_charset = “none”
It Solved my php v7.4.4 application
because i used iconv(‘windows-1256′,’utf-8’, $windowsArabicFileName )

$windowsArabicFileName = “اسم ملف بالعربي.ppt”

RemBem
6 years ago

Thank you, this saved my day, fixing an old site suddenly full of questionmarks after upgrading php. All your other website performance articles are also very helpful!

12
0
Would love your thoughts, please comment.x
()
x