2015-09-07 44 views
0

我正在爲一個網站使用flourishlib。我的客戶要求我們應該可以在手機上使用emojis。理論上,我們應該將字符編碼從utf8更改爲utf8mb4。如何支持emojis蓬勃發展?

到目前爲止,一切都很好,但是,如果我們把這個開關,像這樣:

# 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'"); 

其中,基本上觸發​​執行一個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'」);

如果你看到這段代碼,你可以改變它。

+0

裏克,這個問題被標記爲flourishlib。這意味着它是蓬勃發展的。這意味着如果您對flourishlib沒有任何瞭解,那麼您無法回答。 –

+0

看來你對varchars的爭論是有效的。 –

+0

「向flourishlib投訴或放棄它(這些論壇中的太多問題都是關於第三方軟件包不足的投訴,而不是MySQL本身)」ummm ...問題標籤爲flourishlib,因此這句話完全無效。請閱讀更多關注的問題。我真的很想接受你的答案,但如果你不編輯它們至少解決問題,那麼我將被迫對它們進行投票。 –