問題
最近工作中遇到一個問題,資料庫欄位設置的varchar(255),測試測的時候總是在臨界點那邊給我提bug,今天研究一下mysql和php字符長度判斷。
環境
php7.2.9mysql8.0.12測試時文件的編碼方式要是UTF8資料庫欄位類型大小為 varchar(255),php中用strlen()與mb_strlen()函數。
注意
需要注意的是,mb_strlen並不是PHP核心函數,使用前需要確保在php.ini中加載了php_mbstring.dll,即確保「extension=php_mbstring.dll」這一行存在並且沒有被注釋掉,否則會出現未定義函 數的問題。
分析
考慮到漢字的特殊性,我們測試主要分為兩種,一個是純漢字,一個是純英文字母。
純漢字
準備一個255個漢字的字符串,然後提交資料庫查看結果。
//255個漢字這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個漢字的句子這是個十個php函數的結果
我們在提交前,看一下這兩個php函數分別返回的值是多少
dd(strlen($this->beizhu),mb_strlen($this->beizhu,'UTF8') );結果
可以看出mb_strlen($this->beizhu,』UTF8』),是我們要的結果。
提交到資料庫
提交後發現可以成功保存:
我們把加一個漢字,繼續提交,結果如下:
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'remark' at row 1此時資料庫報錯了。所以,該環境下varchar(255),可以存的漢字數是255個。
純字母
我們以同樣的方式測試字母,首先準備255個字母的字符串。
// 255個字母ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEphp函數的結果
我們在提交前,看一下這兩個php函數分別返回的值是多少
dd(strlen($this->beizhu),mb_strlen($this->beizhu,'UTF8') );結果
字母的情況下,php的strlen和mb_strlen($str,』UTF8』)得到的結果一樣,都是返回255.
提交到資料庫
測試是可以保存的,我們再往裡面加個字母,可以發現報同樣的錯誤。
結論
php在判斷欄位長度的時候用mb_strlen($str,'UTF8'),可以得到和我們輸入字符一樣的結果。
計算時,選定內碼為UTF8,則會將一個中文字符當作長度1來計算,所以「中文a字1符」長度是6 ,雖然上面函數可以簡單解決一些中英文混合問題,但是不能用於實際中,下面我來給各位朋友介紹其它比較好的辦法。PHP獲取中英文混合字符串長度的實現代碼如下,1中文=1位,2英文=1位,可自行修改。
mb_strlen($str,'UTF8')高版本 MySQL 中的 VARCHAR(255) 可以存放 1 - 255 個 UTF-8 格式的字符。