[心得] 可惡的 BIG5

看板PHP作者 (邀怪)時間17年前 (2008/09/18 16:27), 編輯推噓3(309)
留言12則, 5人參與, 最新討論串1/1
想分享一個用 BIG5 做 MySQL + PHP 的不好經驗: 好一陣子在 MySQL 的欄位都用 iso-8859-1 格式存, 也就是把 BIG5 中文當成 英文/Binary 來存檔, 所以可以: $s = "花豹"; // BIG5 的 "豹" 字裡面有一個 '\' 字元 mysql_query("update foo set name='".addslashes($s)."'"); 假設 "花豹" 的 BIG5 內碼是 "xyz\", addslashes 之後變成 "xyz\\", 沒問題. 前一陣子心血來潮, 想說讓我的 MySQL Table 直接用 BIG5 內碼存, 把 Table 轉碼轉好, MySQL 設好, 連 php 裡都加上 mysql_set_charset("big5") 來確定 php 是用 big5 來跟 MySQL 溝通的, 一切 ok, 網頁資料仍然顯示正常, 正高興著, 幾天後才發現像 "豹" 這種剛好有特殊字元的 BIG5 中文字, 根本沒辦法存進去! 因為 addslashes() 不管 BIG5, 還是把 "xzy\" 變成 "xyz\\", 所以那個 query 一樣變成: update foo set name='xyz\\' 但是 MySQL 現在是以 BIG5 當內碼耶!! 所以這個 Query 在 MySQL 看起相當於: update foo set name='花豹\' 也就是前四個 byte 是兩個中文字, 第五個 byte 是單一個 '\', 變成 escape, 整句變成語法錯誤了.... 如果把 addslashes() 拿掉就 OK, 但是存的資料 如果是 "花'豹" 這樣, 一定得要 addslashes() 才能把 ' escape 掉啊.... 結論是, 完全沒辦法讓我既可以存 "花豹" 也可以存 "花'豹", 除非我寫自己的 addslashes() 來辨認 BIG5.... 最後放棄... 唉, 可惡的 BIG5, 浪費我幾天的時間. 我可以理解像 addslashes() 這種 function 加上 encoding support 似乎有點 overkill, 壞人應該還是 BIG5 這種 ambiguous encoding. 你或許會問, 為什麼不要用 UTF-8? 因為輸入跟輸出的資料都必須是 BIG5, 用 UTF-8 得拼命轉碼, 不划算. 最後, 我乖乖的用回 iso-8859-1. 當 binary 存. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 60.251.144.115

09/18 16:40, , 1F
mysql_real_escape_string <-- 請查詢這個函數
09/18 16:40, 1F

09/18 16:53, , 2F
MySQL utf8 , 加上 set names big5;...
09/18 16:53, 2F

09/18 17:04, , 3F
mysql_real_escape_string 的 overhead 很高耶
09/18 17:04, 3F

09/18 17:05, , 4F
因為所有資料都要送到 MySQL 做 escape 再回來
09/18 17:05, 4F

09/18 17:05, , 5F
這樣隨便一個 query 就可能要往返 MySQL 幾百次
09/18 17:05, 5F

09/18 17:06, , 6F
二樓, 這樣就是在拼命轉碼, 只是 MySQL 幫你轉而已
09/18 17:06, 6F

09/18 17:07, , 7F
CPU 會很忙的
09/18 17:07, 7F

09/18 17:17, , 8F
Ya..所以還是兩邊用一樣的編碼比較好...
09/18 17:17, 8F

09/18 20:46, , 9F
不妨參考 #18fwS54Q
09/18 20:46, 9F

09/18 21:47, , 10F
應該不用送到mysql去,它call一個library,要$link,應
09/18 21:47, 10F

09/18 21:47, , 11F
是為了現行編碼的資訊. http://tinyurl.com/4sagad
09/18 21:47, 11F

09/19 01:23, , 12F
真的耶, 早知道我就用它了... 可惡, 都改回來了 Orz
09/19 01:23, 12F
文章代碼(AID): #18qX49h6 (PHP)
文章代碼(AID): #18qX49h6 (PHP)