Welcome to AseanBiz
Facebook Youtube TikTok WhatsApp

Destoon + MariaDB 10.x: Why Your Chinese Text Turns to ???? (and the one-line fix)

   2026-08-22 Vector Digital Works 3
Core Tip: TL;DR — Destoon's database driver compares the MySQL server version as a string instead of a version number. On MariaDB

TL;DR — Destoon's database driver compares the MySQL server version as a string instead of a version number. On MariaDB 10.x, "10.6.27-MariaDB" > "4.1" evaluates to false, so SET NAMES 'utf8' is silently skipped, the connection stays on latin1, and every Chinese character collapses into a single ?. The fix is a one-liner: use version_compare().

The symptom

After migrating a Destoon site to a server running MariaDB 10.x (the default database for DirectAdmin, cPanel, 宝塔/BT, and most LNMP stacks), the entire site's Chinese text turned into ????:

  • The homepage showed 78 places of ????
  • Member shop <title> tags broke
  • The admin sidebar became all ?

Meanwhile the same site on MySQL 5.7 was completely fine. No template changes, no PHP-version issue, no data corruption.

The debugging path (the part that matters)

We first ruled out the usual suspects, because none of them were the cause:

  1. Data intact — a HEX() dump showed the bytes were correct in storage.
  2. Templates fine — the compiled template cache was logically correct.
  3. Connection layer — a minimal probe that replicated Destoon's exact connection path printed conn_charset_now=latin1 and SET NAMES SKIPPED. That was the smoking gun.

The root cause

In module/destoon/db_mysqli.class.php, Destoon decides whether to set the connection charset by comparing the server version as a string:

$version = mysqli_get_server_info($this->connid);
if($version > '4.1' && $this->cfg['db_charset']) {
    mysqli_query($this->connid, "SET NAMES '".$this->cfg['db_charset']."'");
}
if($version > '5.0') {
    mysqli_query($this->connid, "SET SQL_MODE=''");
}

PHP string comparison is lexicographic (character by character, by ASCII value):

  • MariaDB 10.x returns 10.6.27-MariaDB. Comparing against '4.1': first characters '1' vs '4''1' < '4' — the whole string is "less than" 4.1false.
  • So SET NAMES 'utf8' never runs. The connection stays on the server default latin1.
  • MySQL 5.7 returns 5.7.26. '5' > '4'trueSET NAMES runs — Chinese is fine.

That single false on every MariaDB 10.x box is why a "works in dev, breaks in production" mystery happens: your dev box is MySQL 5.x, your production box is MariaDB 10.x.

The fix

Replace string comparison with numeric version comparison:

$version = mysqli_get_server_info($this->connid);
if(version_compare($version, '4.1', '>') && $this->cfg['db_charset']) {
    mysqli_query($this->connid, "SET NAMES '".$this->cfg['db_charset']."'");
}
if(version_compare($version, '5.0', '>')) {
    mysqli_query($this->connid, "SET SQL_MODE=''");
}

version_compare('10.6.27-MariaDB', '4.1', '>') correctly parses 10.6 and returns true.

The result

  • Homepage ????: 78 — 0
  • Member shop <title> restored to correct Chinese
  • Admin sidebar cleared

Why this matters to you

MariaDB 10.x is the default on nearly every shared/VPS control panel. If you run Destoon on MariaDB — or are about to migrate to a host that ships it — you will hit this, regardless of PHP version. Check your db_mysqli.class.php now.

 
Report Favorite 0 Reward 0
More>Similar News
  • admin
  • No signature left~~
Recommend Images
Recommend News
Click Ranking