json - 如何看待/糾正php的array_key_exists函數bug?

來源:互聯網
上載者:User
array_key_exists(0或'0',json_decode('{"0":0})===false

array_key_exists(0或'0',(object)array(0))===true

不能說這是json_decode的鍋,
因為二者var_dump出來雖然一個索引是數字一個是字串,但是畢竟都存在,而且->{0或'0'}訪問沒區別。

實在不行當然只能用第三方json函數,然而php中Null 字元串也不能作為索引,而json規則中並沒有這一條。

真的怕了,php坑太無規律,哪天用著用著又可能有新雷。。

回複內容:

array_key_exists(0或'0',json_decode('{"0":0})===false

array_key_exists(0或'0',(object)array(0))===true

不能說這是json_decode的鍋,
因為二者var_dump出來雖然一個索引是數字一個是字串,但是畢竟都存在,而且->{0或'0'}訪問沒區別。

實在不行當然只能用第三方json函數,然而php中Null 字元串也不能作為索引,而json規則中並沒有這一條。

真的怕了,php坑太無規律,哪天用著用著又可能有新雷。。

RTFM

http://php.net/array_key_exists

For backward compatibility reasons, array_key_exists() will also
return TRUE if key is a property defined within an object given as
array. This behaviour should not be relied upon, and care should be
taken to ensure that array is an array. To check whether a property
exists in an object, use property_exists().

http://php.net/manual/en/language.types.object.php#language.types.object.casting

An array converts to an object with properties named by keys and
corresponding values, with the exception of numeric keys which will be
inaccessible unless iterated.

呃,陸續有人贊這個回答,但是在評論區交流了一番之後覺得一開始的回答是有問題的,感到有些慚愧,所以編輯這個回答

如原答案所說,array_key_exists應該是檢查數組中某個key是否存在的,但是由於曆史原因,array_key_exists支援第二個參數為對象,但這是一個向下相容的設計,官方文檔建議不要依賴這個實現

This behaviour should not be relied upon, and care should be taken to ensure that array is an array.

題主在評論裡提到了json_decode轉換為數組之後再轉換成json會面臨空數組究竟是對應成javascript的Null 物件還是空數組的問題,也許可以看看json_encode的時候加上 JSON_FORCE_OBJECT 這個選項:

php > echo json_encode([]);[]php > echo json_encode([], JSON_FORCE_OBJECT);{}php > echo json_encode(['hello,world']);["hello,world"]php > echo json_encode(['hello,world'], JSON_FORCE_OBJECT);{"0":"hello,world"}

不過這個就變成所有的空數組都強制轉換為對象了,也不見得就一定好用,怎麼用就看題主自己取捨了(或者在js端多加一個額外的判斷?)

下面是原回答

json_decode 第二個參數不帶的話,返回的是一個對象,根本不是數組

以下是php shell執行結果

php > var_dump(json_decode("{\"0\":0}"));class stdClass#1 (1) {  public $0 =>  int(0)}php > var_dump(json_decode("{\"0\":0}", false));class stdClass#1 (1) {  public $0 =>  int(0)}php > var_dump(json_decode("{\"0\":0}", true));array(1) {  [0] =>  int(0)}php > var_dump(array_key_exists(0, json_decode("{\"0\":0}", true)));bool(true)php > var_dump(array_key_exists(0, json_decode("{\"0\":0}", false)));bool(false)php > var_dump(array_key_exists('0', json_decode("{\"0\":0}")));bool(false)
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.