中經(jīng)常遇到的字符串處理問題:編碼、轉義與格式轉換)
在后端開發(fā)過程中有一類問題看起來很簡單但實際開發(fā)和排查問題時經(jīng)常會遇到例如URL 參數(shù)為什么變成了一堆%JSON 字符串為什么多了一層反斜杠Base64 編碼后的內容到底是什么Unicode 字符串如何轉換HTML 實體amp;、lt;是什么意思接口返回的數(shù)據(jù)為什么和數(shù)據(jù)庫里的內容不一樣這些問題通常不值得專門寫一套復雜程序處理但又經(jīng)常需要臨時查看和轉換。平時開發(fā)時可以直接使用 PHP、JavaScript 等代碼處理也可以使用在線工具快速確認數(shù)據(jù)格式。類似的臨時處理我會用 UO在線工具中的文本和開發(fā)類工具輔助檢查。一、URL 編碼到底解決什么問題URL 中并不是所有字符都適合直接傳輸。例如https://example.com/search?keyword你好實際傳輸時中文通常會經(jīng)過 URL 編碼%E4%BD%A0%E5%A5%BD在 PHP 中可以直接使用$url urlencode(你好); echo $url;解碼則使用$text urldecode(%E4%BD%A0%E5%A5%BD); echo $text;開發(fā)接口時如果發(fā)現(xiàn)參數(shù)中出現(xiàn)%E4%BD%A0%E5%A5%BD、%2F、%3D等內容不一定是數(shù)據(jù)異常很可能只是 URL 編碼。這類問題使用 UO在線工具進行臨時編碼、解碼可以比較快地確認原始數(shù)據(jù)。二、JSON 中為什么會出現(xiàn)反斜杠這是接口開發(fā)中非常常見的問題。例如原始 JSON{ name: 張三, age: 20 }經(jīng)過一次字符串化以后可能變成{\name\:\張三\,\age\:20}這里的\并不是 JSON 數(shù)據(jù)本身多出來了而是因為 JSON 又被當成了字符串。PHP 中經(jīng)??梢钥吹筋愃拼a$data array( name 張三, age 20 ); $json json_encode($data); echo $json;結果{name:張三,age:20}如果繼續(xù)echo json_encode($json);就會變成{\name\:\張三\,\age\:20}所以排查接口數(shù)據(jù)時需要先判斷當前變量到底是數(shù)組還是JSON字符串還是JSON字符串再次被JSON編碼很多所謂的“JSON 多了一層反斜杠”實際上都是重復編碼造成的。三、Base64 和加密不是一回事Base64 在接口開發(fā)中也非常常見。例如$str hello; $result base64_encode($str); echo $result;結果aGVsbG8解碼echo base64_decode(aGVsbG8);得到hello需要注意的是Base64 不是加密算法。它只是把二進制數(shù)據(jù)轉換成適合文本傳輸?shù)淖址?。所以Base64(password)并不能作為密碼保護方式。在接口調試、圖片數(shù)據(jù)、Token 參數(shù)、文件內容等場景中經(jīng)??梢钥吹?Base64。如果只是想快速確認一段字符串經(jīng)過 Base64 編碼以后是什么內容在線工具會比臨時寫一個 PHP 文件更加方便。四、HTML 實體也是一種常見的字符串問題網(wǎng)頁內容中經(jīng)常會出現(xiàn)lt; gt; amp; quot;例如lt;divgt;Hellolt;/divgt;實際上對應divHello/divPHP 中可以使用htmlspecialchars(divHello/div);進行 HTML 特殊字符轉義。反過來如果需要恢復 HTML 實體可以使用htmlspecialchars_decode(lt;divgt;Hellolt;/divgt;);這類數(shù)據(jù)在爬蟲、富文本、接口返回、數(shù)據(jù)庫存儲以及模板渲染中都比較常見。五、Unicode 轉義接口調試的時候還可能看到這樣的內容\u4f60\u597d它實際上代表你好JSON 中使用 Unicode 轉義并不代表數(shù)據(jù)損壞。例如{ message: \u4f60\u597d }解析以后得到的就是{ message: 你好 }PHP 中$data json_decode($json, true); echo $data[message];就可以直接獲取中文。因此看到接口返回\u4e2d\u6587時第一反應應該是判斷它是不是 JSON Unicode 轉義而不是直接認為接口亂碼。六、字符串出現(xiàn)亂碼時先檢查編碼亂碼問題通常不能只看頁面。常見編碼包括UTF-8 GBK GB2312 ISO-8859-1現(xiàn)在 Web 項目基本以 UTF-8 為主。PHP 文件一般建議使用 UTF-8 編碼。HTMLmeta charsetUTF-8數(shù)據(jù)庫連接也需要注意字符集。例如 MySQLSET NAMES utf8mb4;如果 PHP、MySQL、HTML 三個環(huán)節(jié)使用的字符集不一致就可能出現(xiàn)或者中文顯示異常。所以遇到亂碼時不要只修改頁面字體應該從數(shù)據(jù)源 → PHP → 數(shù)據(jù)庫 → HTTP響應 → 瀏覽器整個鏈路檢查。七、開發(fā)中經(jīng)常需要處理哪些字符串后端開發(fā)中比較常見的臨時字符串處理包括JSON格式化 URL編碼/解碼 Base64編碼/解碼 Unicode轉換 HTML實體轉換 字符串轉義 文本去重 大小寫轉換 空白字符處理 正則表達式測試這些功能本身都不復雜但開發(fā)過程中經(jīng)常需要臨時處理一段數(shù)據(jù)。比如接口返回了一大段壓縮后的 JSON{id:1001,name:test,items:[{id:1},{id:2}]}如果直接查看會比較困難格式化以后{ id: 1001, name: test, items: [ { id: 1 }, { id: 2 } ] }排查字段結構就會方便很多。同樣如果拿到一段 URL 編碼或者 Base64 數(shù)據(jù)也可以先轉換成可讀內容再繼續(xù)分析。八、在線工具和本地代碼怎么選擇對于正式業(yè)務邏輯還是應該寫進程序。例如$timestamp time(); $json json_encode($data); $base64 base64_encode($content);這些屬于業(yè)務代碼應該由程序自動處理。而下面這種情況臨時看一下某個 JSON 確認一個時間戳對應什么時間 測試一下正則 判斷一段字符串是不是 Base64 臨時進行 URL 編碼使用在線工具會更加直接。所以在線工具更適合解決開發(fā)過程中的“小問題”而不是替代 IDE、調試器或者項目代碼。九、敏感數(shù)據(jù)不要直接提交到在線工具使用在線工具處理數(shù)據(jù)時還需要注意數(shù)據(jù)安全。以下內容不建議直接復制到第三方在線工具用戶密碼 AccessKey SecretKey Token 數(shù)據(jù)庫密碼 身份證號碼 銀行卡信息 生產環(huán)境密鑰 內部業(yè)務數(shù)據(jù)如果只是測試格式可以先進行脫敏。例如真實手機號 13812345678 測試數(shù)據(jù) 13800000000接口返回的數(shù)據(jù)也可以只保留結構把真實業(yè)務數(shù)據(jù)替換掉。對于生產環(huán)境問題優(yōu)先使用本地腳本、開發(fā)環(huán)境或者服務器上的調試工具。十、總結后端開發(fā)中有很多問題并不復雜但非常容易浪費時間。尤其是JSON URL 編碼 Base64 HTML 實體 Unicode 字符集 字符串轉義這些內容單獨看都很簡單但在接口開發(fā)和問題排查過程中出現(xiàn)的頻率并不低。把常用的臨時處理功能集中起來可以減少頻繁搜索和重復寫測試代碼的時間。這類開發(fā)過程中經(jīng)常用到的在線小工具我整理到了UO在線工具https://uotool.com目前主要包含 JSON、文本、編碼轉換、開發(fā)輔助等常見工具適合處理一些簡單、臨時、非敏感的數(shù)據(jù)。對于正式項目還是應該以代碼和本地開發(fā)環(huán)境為主對于簡單的臨時數(shù)據(jù)處理在線工具可以作為一個補充。