由數據庫某字段存數組引發的json_encode/serialize思考
導火索場景:
- 原來:mysql中 result表 img字段原存儲字符串,內容為某圖片鏈接;
- 現在:該字段需要存儲多張圖片鏈接,1-3個元素行程的數組;
google得到的普遍建議有兩種: https://stackoverflow.com/questions/3413291/how-to-store-an-array-into-mysql
- 建議一:根據具體場景構建多張表,通過主鍵外鍵形成關聯。
優點:支持針對數組中某個字段的查詢等;缺點:需要結合具體場景
- 建議二:序列化數組,php提供內置方法支持序列化與反序列化(serialize / unserialize)(開發完後發現仍存在另一種序列化方式json_encode / json_decode
優點:方便實現;缺點:數組被看作整體,不支持對單個元素的操作;
不存在針對單個圖片鏈接的查詢等操作,選擇建議二。
問題:接口postman img參數一欄值寫 [xxx,xxx],序列化後入庫,獲取時反序列化預期返回數組的出參 [xxx,xxx],實則返回string類型的 "[xxx,xxx]"
排查過程:在php中gettype查看數據類型,入參實則為string類型,json_decode後才為array類型
原因:postman img參數一欄值寫 [xxx,xxx],此時其實為string類型,json類型的數組。
後續一:對json類型的了解一直過於膚淺,乘此機會學習之,相關資料讓我茅塞頓開,總結分享如下。
1. json可以理解為符合一定書寫格式的字符串,實質仍是string;
2. json具體的格式規則可以總結為4句話
3. json只接受utf-8編碼的字符,所以json_encode()的參數必須是utf-8編碼,否則會得到空字符或者null,
起初看了json的文檔,就是被這些規則,[],{}混亂了,但看到下面一段話就通了。來源(阮一峰:數據類型和json格式)
它說,從結構上看,所有的數據(data)最終都可以分解成三種類型:
第一種類型是標量(scalar),也就是一個單獨的字符串(string)或數字(numbers),比如"北京"這個單獨的詞。
第二種類型是序列(sequence),也就是若幹個相關的數據按照一定順序並列在一起,又叫做數組(array)或列表(List)
,比如"北京,上海"。第三種類型是映射(mapping),也就是一個名/值對(Name/value),即數據有一個名稱,還有一個與之相對應的值,這又稱作散列(hash)或字典(dictionary),比如"首都:北京"。
現在,任何的數據類型都可以歸並到以上三類中。數組表示有序數據的集合,而對象表示無序數據的集合。如果數據的順序很重要,就用數組,否則就用對象
而我的[],{}混亂也解決了,[]對應的為序列,也可稱為索引數組;{}對應的為映射,也可稱為關聯數組。來源:阮一峰:在PHP語言中使用json
json_encode和json_decode在第二三種類型上的操作則可理解為string類型和映射或序列之間的轉換;對於標量來說,則是進行編碼轉義(只搜到底層會unicode,具體未找到?)
//序列,索引數組 $arr = Array(‘one‘, ‘two‘, ‘three‘); echo json_encode($arr); //["one","two","three"] //映射,關聯數組 $arr = Array(‘1‘=>‘one‘, ‘2‘=>‘two‘, ‘3‘=>‘three‘); echo json_encode($arr); // {"1":"one","2":"two","3":"three"} //特別說明,映射的decode $json = ‘{"a":1,"b":2,"c":3,"d":4,"e":5}‘; var_dump(json_decode($json)); //默認生成stdClass對象 object(stdClass)#1 (5) { ["a"] => int(1) ["b"] => int(2) ["c"] => int(3) ["d"] => int(4) ["e"] => int(5) } var_dump(json_decode($json,true)); //加參數true,指定生成關聯數組 array(5) { ["a"] => int(1) ["b"] => int(2) ["c"] => int(3) ["d"] => int(4) ["e"] => int(5) }
後續二:序列化
何時需要序列化?
復雜數據結構在php腳本執行過程在內存中存儲,但不可用於直接傳輸/存儲入庫等。
序列化的實質是什麽?
數據結構存儲會有對應的數據結構,序列化實則可以理解為降維的過程。
json_encode/serialize的區別?
都是序列化生成字符串的過程,采用不同的規則。自我理解,serialize是php 3.05開始支持,生成字符串更為緊湊,json_encode是PHP 5.2之後支持,可讀性更好。
更新區別:
JSON vs. Serialized Array in database [closed]
Preferred method to store PHP arrays (json_encode vs serialize)
基本評價是,json的易讀性更好、速度更快、序列化後存儲空間更小。
只在以下幾種情況不選擇json:
1. 使用php版本過低,不支持;
2. 需要存儲的復雜結構元素過多,超過127個元素,json將返回錯誤;
3. 需要保留類名等信息
由數據庫某字段存數組引發的json_encode/serialize思考