PHP 對空字串的 json_encode 跟 json_decode

這兩天好好的研究一下 php 的 source code ,接著打算試著回饋補釘給 php 上游 因此我到 php bug reporting 找了一個看起來蠻簡單的 bug 來修 傳送門

把重點整理出來一下

Test script:
---------------
var_dump( json_decode( json_encode( "" ) ) );


Expected result:
----------------
null

Actual result:
--------------
string '' (length=0)

看起來像是簡單的 bug ,我想說真的賺到了一個簡單的 bug 可以練習,只是不知道為什麼這種簡單的 bug 都沒人來修呢?
怎麼可能放了這麼久都沒人遇到。

這個 bug 我想是因為遇到了下面這種狀況

var_dump(json_decode("")); # 回傳 null

所以直覺上認為他寫的測試程式碼也應該得到 null 。

這裡其實很正常,json_decode 是把 php 的字串轉成 json 物件,所以 json_decode("") 時,因為字串裡面什麼東西都沒有,所以 php 會轉成 null (因為最外面那層引號是給 php 看的,實際上要變成 json 字串根本沒東西存在)


接著就是原 PO 對 encode 跟 decode 所產生的誤會了。

json_encode("") 是要把 php 物件轉變成 json 的字串,所以既然現在 encode 的東西是空字串,那麼為了讓 json 讀懂,
所以 php 會產生一個字串裡頭包含要給 json 看的 ""

這時候如果把這個變數 dump 出來會看到 string(2) """" ,這個意思就是我是個 php 字串,裡面包含 "" 這兩個字元 所以如果再去 decode 一遍的話,當然很自然的會還原成 php 的空字串,
而且同一個東西 php -> json, json -> php 還原回來成一樣的東西是個正確的行為。

所以我想這個原 PO 似乎又沒看清楚誰是誰的括號了,我這篇有探討了一下引號的特性,有興趣可以看一下。


附帶一提,虧我已經把針對特殊狀況的 patch 寫好,要送出我人生第一個送回上游的 patch 了,結果是個烏龍 bug。