2017-10-10 77 views
4

我正在從文件中讀取JSON字符串,解析它,然後將數據插入MySQL數據庫。我插入查詢拋出以下錯誤:文件讀取到數據庫插入導致unicode字符串

SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xE3\xADs' for column 'fname' at row 1 

我相信導致錯誤的內容是在名稱Ailís(我呼應的ID,直到錯誤被拋出)的í

  • 該文件是UTF8使用UTF8上下文
  • 我檢查的數據的編碼是UTF8(它是)
  • 我的PDO連接具有UTF8編碼
  • 我讀該文件字符集,以及SET NAMES utf8
  • 該數據庫是UTF8編碼
  • 該表是UTF8編碼
  • 列是UTF8編碼

代碼:

$opts = ['http' => ['header' => 'Accept-Charset: UTF-8, *;q=0']]; 
$context = stream_context_create($opts); 
$post = file_get_contents('sample_data/11111a_json_upload.json',false, $context); 
if(!mb_check_encoding($post, 'UTF-8')) 
    throw new Exception('Invalid encoding detected.'); 
$data = json_decode($post, true); 

我還插入下面的函數之前,我解碼的JSON:

static function clean_unicode_literals($string) 
{ 
    return preg_replace_callback('@\\\(x)?([0-9a-zA-Z]{2,3})@', 
     function ($m) { 
      if ($m[1]) { 
       $hex = substr($m[2], 0, 2); 
       $unhex = chr(hexdec($hex)); 
       if (strlen($m[2]) > 2) { 
        $unhex .= substr($m[2], 2); 
       } 
       return $unhex; 
      } else { 
       return chr(octdec($m[2])); 
      } 
     }, $string); 
} 

當我讀到的原始文件,當我解析的數據回顯到瀏覽器,名稱顯示正確。因此,我認爲這個問題與我有關?

我創建了一個新的PDO實例,像這樣:

public function __construct($db_user, $db_pass, $db_name, $db_host, $charset) 
{ 
    if(!is_null($db_name)) 
     $dsn = 'mysql:host=' . $db_host . ';dbname=' . $db_name . ';charset=' . $charset; 
    else 
     $dsn = 'mysql:host=' . $db_host . ';charset=' . $charset; 

    $options = [ 
     PDO::ATTR_PERSISTENT => true, 
     PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
     PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'" 
    ]; 

    try 
    { 
     $this->db_handler = new PDO($dsn, $db_user, $db_pass, $options); 
     $this->db_handler->exec('SET NAMES utf8'); 
     $this->db_valid = true; 
    } 
    catch(PDOException $e) 
    { 
     $this->db_error = $e->getMessage(); 
     $this->db_valid = false; 
    } 

    return $this->db_valid; 
} 

(SET NAMES有兩次我排除故障......)
數據庫,表和列字符集設置爲utf8_general_ci

我的IDE是PHPStorm,而我在Windows上運行WAMP的MySQL 5.7.14 10

+0

那麼實際上插入的代碼在哪裏? – Sammitch

回答

1

東西肯定是不對的輸入字符串:\xE3\xADs

的前半部分E表明,它應該是一個3字節的UTF-8序列,但只有兩個字節。

而且它絕對不是í,因爲這是雙字節序列\xC3\xAD

我不得不想知道爲什麼你有那個clean_unicode_literals函數,因爲根據JSON規範,所有JSON字符串和文檔都應該是有效的UTF-8。

嘗試刪除clean_unicode_literals調用,並且如果您仍然收到錯誤,那麼源數據已損壞。