關於MYSQL Incorrect string value


  • 當用戶發表有某些特殊字符的內容時,存入MYSQL數據庫的內容會被截斷;
  • 數據庫、程序文件等都是UTF-8編碼
  • 確認SQL語句正常
  • MYSQL中UTF-8編碼最多只能是3個字節(5.5.3版本后,有 utf8mb4類型可支持4個字節的utf8);
  • utf8是一種1-4個字節的可變字符編碼(英文1個字符,漢字3個字符);
  • 某些特殊字符(emoji表情符號等)是4字節的utf8編碼;
  • MYSQL在遇到超過最大字節范圍的字符時,會忽略其后面的字符串,從而導致內容丟失。
  • 升級MYSQL到5.5.3版本以上,並將字段的編碼設置為utf8mb4類型;
  • 通過程序,將字符串中4字節的utf8字符替換或者刪除即可。
    function removeByte4($str){
        return preg_replace('/[\xF0-\xF7].../s','', $str);
    }

 

台式機,4.6W字符,0.006s,對程序性能影響基本可以忽略。

該問題是mysql本身的一個bug,可參考"Incorrect string value" error (1366) when inserting special characters“

  • windows xp: xp系統不支持4字節utf8字符, 瀏覽器用占位符顯示;
  • windows 7: 支持4字節utf8字符;
  • mac os x: 支持4字節utf8字符;
  • iPhone/iPad: 支持4字節utf8字符;

此問題可參考mysql utf8mb4與emoji表情

  • 將特殊的4字節字符用相應的圖片表情代替;
  • 替換的時候,注意不要堵塞用戶的處理流程,當文本內容較長時,這是一個很耗性能的處理,建議先忽略4字節字符,然后將內容存到文件或者其他地方,后續使用腳本對這些內容進行替換處理等操作。;
  • 新浪微博等有做相應處理;
  • 特殊符合以及對應表情可參考[網站](http://www.charbase.com/);

測試機:普通pc; 測試文本:4.6W字節的中英文、特殊字符等混合;

極快,推薦使用:0.006s

    function removeByte4($str){
        return preg_replace('/[\xF0-\xF7].../s','', $str);
    }

 

較慢,參考用:0.2s

    function removeByte4_2($str){
        return preg_replace('/[\x{10000}-\x{10FFFF}]/u','', $str);
    }

 

慢,但方便對特殊字符做不同替換:3s

    function removeByte4_1($str){//移除utf-8編碼中4字節及以上的字符
        mb_internal_encoding("UTF-8");
        $len = mb_strlen($str);
        $res = '';
        for($i=0;$i<$len;$i++){
            $t = mb_substr($str,$i,1);
            $res .= strlen($t)<=3?$t:'';
        }
        return $res;
    }

 

極慢,不具使用價值,僅參考:10.9s

    function remove_4_byte($string) {
        $char_array = preg_split('/(?<!^)(?!$)/u', $string );
        $len = count($char_array);
        for($x=0;$x<$len;$x++) {
            if(strlen($char_array[$x])>3) {
                $char_array[$x] = "";
            }
        }
        return implode($char_array, "");
    }

 

轉自: Vien Dave's Blog

相關:關於 MySQL UTF8 編碼下生僻字符插入失敗/假死問題的分析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM