2015-05-20 47 views
0

讓兩個小測試開始:爲什麼PHP函數「json_encode」應用於第一個元素缺失的非關聯數組會將第二個關鍵字視爲字符串?


$original = [0 => 'a', 1 => 'b']; 
var_dump((json_decode(json_encode($original)))); 

回報

array(2) { // array 
    [0]=> // integer like original 
     string(1) "a" 
    [1]=> // integer like original 
     string(1) "b" 
} 

所以我們可以在這裏看到,該assoc參數(在json_decode函數的第二個參數)未設置(默認爲false ),並且配對json_decode-json_encode恢復原來的樣子。


$original = [1 => 'a', 2 => 'b']; 
var_dump((json_decode(json_encode($original)))); 

回報

object(stdClass)#1 (2) { // object 
    ["1"]=> // string, instead of integer 
     string(1) "a" 
    ["2"]=> // string, instead of integer 
     string(1) "b" 
} 

在這裏,assocfalse,但除非我們明確設定assoctruejson_decode-json_encode無法恢復原來的。


問:我上的自定義序列化過程(從PHP serializeunserialize功能不同的)工作。我決定使用json_decode-json_encode對,我發現我不能依靠默認設置,如assoc=false。您是否知道json_家族功能有任何其他缺陷,當我無法恢復原始數據和結構時,可能會導致出現問題?

回答

3

的JSON編碼數組的樣子:

[ element, element, element, ... ] 

正如你所看到的,有沒有明確的指標,所以當數組包含從0

開始的連續數字索引只能用這個編碼

任何其他數組都被編碼爲對象,並且對象鍵始終是JSON中的字符串。當您使用json_decode()對對象進行解碼時,如果assocfalse,則返回一個PHP對象,如果是true,則返回一個關聯數組。

當你通過JSON編碼處理的對象,有沒有辦法告訴原來的陣列是否有數字或字符串索引。他們將永遠成爲JSON字符串。

此外,當您使用assoc = false,並且結果是對象時,屬性必須是字符串,因爲PHP對象不能有數字屬性名稱。

當您使用assoc = false你恢復原來的,因爲PHP本身並沒有數字和數字之間的字符串作爲數組索引相區別。如果你這樣做:

var_dump(array('1' => 'a', 2 => 'b')); 

結果是:

array(2) { 
    [1]=> 
    string(1) "a" 
    [2]=> 
    string(1) "b" 
} 

正如你所看到的,PHP創建數組的時候自動開啓串'1'成數1

JSON從未打算用於在沒有信息丟失的情況下用任何語言編碼對象。它被設計成一種簡單的格式,便於用不同語言編寫的應用程序之間的通信。所以它將很多細節抽象出來,並且只支持基本的數組和對象。 XML和serialize等其他格式允許更高的精度。

+1

那麼,他們可以在編碼上執行'JSON_NUMERIC_CHECK'。 –

+0

隻影響值,而不是鍵。 – Barmar

+0

謝謝。那麼,這個問題我們有3個選項(一個有3個元素的數組)存儲爲JSON編碼的字符串。後來我們決定擺脫第一種選擇,所以我們解碼了字符串 - >刪除[0]元素 - >編碼了字符串,然後在數組變成對象時遇到了這個問題。 – Axalix

相關問題