Search code examples
phpmysqlutf-8special-charactersutf8mb4

MySQL Database stores question marks instead of special characters


I am trying to displaying VERY Special Characters (like 𝑻𝒆𝒔𝒕 𝒐𝒏𝒆 𝒕𝒘𝒐 𝒕𝒉𝒓𝒆𝒆) inside of my website, and storing it into my database. When I write special characters like those, they get once displayed, but when I reload the page and the server gets the string from the Database, it gets displayed as "??????? ?????? ?????? ??????" I tried to do a lot of things to fix this, but none of them worked. This isn't a visualization problem, because the header is set right:

<meta charset="utf-8">

What I did try to do:

  • Setting the server's default charset to utf8.
  • Setting the database/table/column collapse and charset to utf8mb4_unicode_ci
  • Changing the connect string to:
$db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

$db->query("SET character_set_results=utf8mb4");

mb_language('uni'); 

mb_internal_encoding('UTF-8');

$db->query("SET NAMES utf8mb4");

$db->set_charset('utf8mb4');

But nothing of this things worked. As an addition, I tried (Just for debugging) to change a string in the text field of the database to 𝑻𝒆𝒔𝒕 𝒐𝒏𝒆 𝒕𝒘𝒐 𝒕𝒉𝒓𝒆𝒆, and I got an error:

Warning: #1300 Invalid utf8 character string: 'F09D91'

Warning: #1366 Incorrect string value: '\xF0\x9D\x91\xBB\xF0\x9D...' for column 'text' at row 1

I tried really every solution I found here and outsite, but nothing worked. Any help would be appreciated.


Solution

  • As discussed in comments.

    In many cases, you need to place all of the code following
    $db->query("SET character_set_results=utf8mb4"); before that line.

    Also using a different file encoding could also help.

    I've had to do that myself before, oddly enough. It could also be the server's default encoding that may be overriding something, somewhere; I've had that problem before also.

    Plus, if you're querying somewhere, as in doing a SELECT, UPDATE or INSERT, then it is important that the encoding codes are placed before the query, should that be the case.