Как поддержать Emojis с процветать?

Я использую flourishlib для веб-сайта. Мой клиент попросил, чтобы мы могли использовать эмодзи с мобильными телефонами. Теоретически мы должны изменить кодировку символов с utf8 на utf8mb4 для базы данных MySQL.

Пока все хорошо, однако, если мы сделаем это переключение, вот так:

# For each database:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE utf8mb4_unicode_ci;
# For each table:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# For each column:
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# (Don’t blindly copy-paste this! The exact statement depends on the column type, maximum length, and other properties. The above line is just an example for a `VARCHAR` column.)

Тогда каждый символ будет использовать четыре байта вместо трех байтов. Это увеличит размер базы данных на 33%. Это может привести к снижению производительности и увеличению занимаемого пространства. Поэтому в результате мы решили перейти на кодировку utf8mb4 только для определенных столбцов определенных таблиц.

Чтобы убедиться, что все в порядке, я проверил несколько вещей. Среди них я проверил flourishlib и нашел несколько подозрительных частей:

  1. Существует класс fUTF8, который не поддерживает utf8mb4

  2. В fDatabase я цитирую некоторые выводы:

    if ($this->connection && function_exists('mysql_set_charset') && !mysql_set_charset('utf8', $this->connection)) {
    throw new fConnectivityException(
    'There was an error setting the database connection to use UTF-8'
    );
    }
    //...
    // Make MySQL act more strict and use UTF-8
    if ($this->type == 'mysql') {
    $this->execute("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'");
    $this->execute("SET NAMES 'utf8'");
    $this->execute("SET CHARACTER SET utf8");
    }
    
  3. В fSQLSchemaTranslation я вижу это:

    $sql = preg_replace('#\)\s*;?\s*$#D', ')ENGINE=InnoDB, CHARACTER SET utf8', $sql);
    

У меня есть подозрение, что flourishlib не будет поддерживать наш квест по созданию нескольких столбцов таблицы с кодировкой символов utf8mb4. Интересно, сможем ли мы что-то обновить, чтобы сделать эту поддержку. В худшем случае мы можем переопределить каждое текстовое вхождение utf8 в utf8mb4. Тем не менее, это было бы очень уродливо, и мы задаемся вопросом, есть ли лучшее решение. Должны ли мы сделать этот взлом или есть более ортодоксальный подход?

0

Решение

Я решил проблему. Я изменил таблицы, в которых я хотел поддержать эмодзи, изменив набор символов столбца и параметры сортировки, например:

ALTER TABLE table_name CHANGE column_name column_name text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

После этого мне пришлось сделать несколько уродливых хаков, чтобы сделать flourishlib способным поддерживать смайлики.

fDatabase.php:

строка 685:

        if ($this->connection && function_exists('mysql_set_charset') && !mysql_set_charset('utf8mb4', $this->connection)) {
throw new fConnectivityException(
'There was an error setting the database connection to use UTF-8'
);
}

строка 717 остается прежней, все падает, если эта строка изменяется:

if ($this->connection && function_exists('mysqli_set_charset') && !mysqli_set_charset($this->connection, 'utf8')) {

строка 800:

    // Make MySQL act more strict and use UTF-8
if ($this->type == 'mysql') {
$this->execute("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'");
$this->execute("SET NAMES 'utf8mb4'");
$this->execute("SET CHARACTER SET utf8mb4");
}

fSQLSchemaTranslation.php:

строка 1554:

$sql = preg_replace('#\)\s*;?\s*$#D', ')ENGINE=InnoDB, CHARACTER SET utf8mb4', $sql);

fXML.php:

строка 403:

    if (preg_replace('#[^a-z0-9]#', '', strtolower($encoding)) == 'utf8mb4') {
// Remove the UTF-8 BOM if present
$xml = preg_replace("#^\xEF\xBB\xBF#", '', $xml);
fCore::startErrorCapture(E_NOTICE);
$cleaned = self::iconv('UTF-8', 'UTF-8', $xml);
if ($cleaned != $xml) {
$xml = self::iconv('Windows-1252', 'UTF-8', $xml);
}
fCore::stopErrorCapture();
}

и наконец, когда есть изменения для любого из затронутых столбцов, я выполняю это:

App::db()->query("set names 'utf8mb4'");

который, по сути, вызывает ->query() исполнение fDatabase объект.

1

Другие решения

увеличить размер базы данных на 33%.

Не правда. Английские буквы по-прежнему занимают 1 байт каждая. То, что вы получаете с utf8mb4, это способность хранить эмодзи и некоторые китайские иероглифы.

Вам не нужно ALTER ... CHANGE колонны. За исключением того, что вы, вероятно, имели консервы VARCHAR(255) у которого есть проблемы. Не просто переключитесь на 191, переключитесь на «разумный» номер для каждого столбца. Или ничего не делать. 191 приходит только от INDEX ограничение. Вы не индексируете каждый колонна, ты?

класс fUTF8, который, кажется, не поддерживает

Пожаловаться на flourishlib. Или оставь это. (Слишком много вопросов на этих форумах — жалобы на неадекватные сторонние пакеты, а не на MySQL.)

Вы может быть быть в состоянии изменить на utf8mb4 в MySQL и позволить flourishlib не замечать этого изменения. Технически говоря, MySQL utf8mb4 соответствует остальной концепции мира utf8; MySQL utf8 является неполной реализацией.

$ this-> execute («SET NAMES ‘utf8′»);

Если вы видите этот код, вы можете изменить его.

-1

По вопросам рекламы [email protected]