Luke
Luke

Reputation: 23700

Post values encoding issue. £ turning into £

I'm trying to solve an issue with my website. If I submit a form containing the £ symbol to the same page, it comes back as £ even before it hits my database.

I have tried the following in my tag:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

and

<meta charset="utf-8">

I've tried all of these at the start of every page:

header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('utf-8');
ini_set('default_charset', 'utf-8');

I also have the SET NAMES in my database connection string:

new PDO("mysql:host=localhost;dbname=########", "##########", "######", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

At first I thought it was my database, because the values were being stored in there with these values - however I have realised if I submit my form and it has validation errors, I pick up the submitted value via $_POST[] and it returns the value in the textbox with the strange characters.

It works perfectly fine on my local WAMP server, but when I run my website in my live environment - this is when I hit the problem with the encoding.

Does anyone have any other suggestions that I can try to fix it?

Upvotes: 0

Views: 177

Answers (1)

h2ooooooo
h2ooooooo

Reputation: 39550

Your problem is that your live server uses a PHP version less than 5.4.0, and hence when you use htmlentities it defaults to ISO-8859-1, as the manual specifies:

Like htmlspecialchars(), htmlentities() takes an optional third argument encoding which defines encoding used in conversion. If omitted, the default value for this argument is ISO-8859-1 in versions of PHP prior to 5.4.0, and UTF-8 from PHP 5.4.0 onwards.

You can fix this by using UTF-8 as the third parameter, or simply make your own function that defaults to it:

if (!function_exists('htmlentities_utf8')) {
    function htmlentities_utf8($string, $flags = null, $encoding = 'UTF-8', $double_encode = true) {
        if ($flags === null) {
            $flags = ENT_COMPAT | ENT_HTML401;
        }

        return htmlentities($string, $flags, $encoding, $double_encode);
    }
}

Alternatively, if you ever plan on using another encoding, you can make it grab the default_charset value:

if (!function_exists('htmlentities_dc')) {
    function htmlentities_dc($string, $flags = null, $encoding = null, $double_encode = true) {
        if ($flags === null) {
            $flags = ENT_COMPAT | ENT_HTML401;
        }

        if ($encoding === null) {
            $encoding = ini_get('default_charset');
        }

        return htmlentities($string, $flags, $encoding, $double_encode);
    }
}

Upvotes: 1

Related Questions