如何支持emojis蓬勃发展?

时间:2015-09-07 21:49:31

标签: php mysql utf-8 utf8mb4 flourishlib

我在网站上使用flourishlib。我的客户要求我们应该能够将emojis与手机配合使用。从理论上讲,我们应该将MySQL数据库的字符编码从utf8更改为utf8mb4。

到目前为止,如果我们进行此转换,那么很好,就像这样:

# 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的编码。

为了确保一切正常,我已经检查了几件事。其中,我检查了一些可疑的部分:

  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);
    
  4. 我怀疑flourishlib不支持我们要求使几个表的几列具有utf8mb4的字符编码。我想知道我们是否可以某种方式升级某些东西以获得这种支持。在最坏的情况下,我们可以将utf8的每个文本出现覆盖为utf8mb4。然而,这将是一个非常丑陋的黑客,我们想知道是否有更好的解决方案。我们应该做这个黑客还是有更正统的方法?

2 个答案:

答案 0 :(得分:1)

我已经解决了这个问题。我通过更改列字符集和排序规则来改变我想要支持表情符号的表格,如下所示:

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

在那之后,我不得不制作一些丑陋的黑客,以使蓬勃发展能够支持表情符号。

<强> 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 :(得分:-1)

  

将数据库的大小增加33%。

不正确。英文字母每个仍然需要1个字节。你通过utf8mb4获得的是用于存储表情符号和一些中文字符的能力

您不应该ALTER ... CHANGE列。除了你可能有一个有问题的罐头VARCHAR(255)。不要只是切换到191,切换到合理的&#39;每列的编号。或者什么也不做。 191仅来自INDEX限制。您没有为每个列编制索引,是吗?

  

fUTF8类,似乎不支持

抱怨蓬勃发展。或者放弃它。 (在这些论坛中有太多问题是关于第三方软件包不足的投诉,而不是MySQL本身。)

可能能够在MySQL中更改为utf8mb4并让蓬勃发展的人忘记这一变化。从技术上讲,MySQL的utf8mb4符合世界其他地区的utf8概念; MySQL的utf8是一个不完整的实现。

  

$ this-&gt;执行(&#34; SET NAMES&#39; utf8&#39;&#34;);

如果您能看到此代码,则可以进行更改。