2017-09-01 39 views
2

這是不是真的那麼函數實現因版本有時會改變,但不是這樣的驚喜不同的結果...查看:get_object_vars返回根據PHP版本

對於5.6.x,然後例如7.0.17和7.1.3,我們得到:

array(2) { 
[0]=> string(3) "abc" 
[1]=> string(3) "def" 
} 

但對於7.0.0和7.0.16和7.1.0,我們得到:

array(2) { 
["0"]=> string(3) "abc" 
["1"]=> string(3) "def" 
} 

演示:https://3v4l.org/jog4A

看到了嗎?這些鍵是整數或字符串,具體取決於版本。

爲什麼?這些變化背後的推理是什麼?爲什麼這沒有記錄在任何地方?或者...是嗎?

回答

1

如果你對3v4.org輸出的版本更密切地關注,它在7.0.0被打破直至幷包括7.0.16和7.1.0直至幷包括7.1 0.2。所以這是7.0中引入的一個錯誤,並且在7.0.17和7.1.3(兩個發佈日期爲2017年3月16日)的時候都在兩個活動版本中得到修復。

看着the PHP changelog我們可以看到相關的尋找條目:

更正了BUG#73998(array_key_exists失敗對數組由get_object_vars創建)。

這使我們the bug tracker,並從那裏到commit dd9cf23457e21d2bda29dc92d437b9dbd14027b2 in th git repo

BUG#73998:數值屬性不是從get_object_vars

的修復包括將用於:如果在檢查無障礙設施是數字鍵,如果存在,則跳過標有「fast_copy」的塊。

因此,這是PHP 7開發過程中性能優化的不良副作用,現已在所有支持的版本中得到修復。

有趣的是,安德烈評論描述的一般問題的錯誤報告,這是密切相關的an RFC to change the behaviour of object-to-array casts

因爲數組和對象有不同的限制對他們能有什麼類型的密鑰的基本哈希表型有,Zend引擎必須在實現數組和對象本身的代碼中的HashTables之上的層上強制執行它們的限制。這意味着如果繞過代碼並直接修改底層的HashTables,則數組和對象可能存在無效的內部狀態。

和由RFC尋址的具體情況下:

例如,$ ARR = [0 => 1,1 => 2,2 => 3]; $ obj =(object)$ arr;產生一個名爲1和2的不可訪問屬性的對象,而$ obj = new stdClass; $ obj - > {'0'} = 1; $ obj - > {'1'} = 2; $ obj - > {'2'} = 3;生成一個數組,其中包含無法訪問的鍵「0」,「1」和「2」。使用get_object_vars()時也會發生同樣的問題。

的RFC在7.2.0中實現,因爲它改變了記錄的行爲,但get_object_vars()行爲實際上是一個意外的變化在7.0,因此被實現爲一個bug修復。

+0

謝謝!我相信這是答案:) – konrados

0

其實這是一個錯誤,因爲變量必須以字母開頭。

變量名稱遵循與PHP中其他標籤相同的規則。有效的 變量名以字母或下劃線開頭,後面跟着任意數字的字母,數字或下劃線。爲正則表達式, 它將被表述爲: '[A-ZA-Z_ \ x7f- \ XFF] [A-ZA-Z0-9_ \ x7f- \ XFF] *'

http://php.net/manual/en/language.variables.basics.php

所以當你試圖設置變量$object->$index = $value;它必須拋出一個錯誤(你不能設置變量像這樣$1 = 'foo';$obj->1 = 'foo';)。

array(2) { 
["0"]=> string(3) "abc" 
["1"]=> string(3) "def" 
} 

是正確的結果,因爲get_object_vars返回關聯數組。

返回值¶

返回對象定義可訪問的非靜態 屬性在範圍指定對象的關聯數組。如果一個屬性沒有給 分配一個值,它將返回一個NULL值。

http://php.net/manual/en/function.get-object-vars.php

+1

所以你的意思是它在php7中的錯誤? 根據get-object-vars鏈接,它應該在php5.6中以字符串的形式返回鍵值。你能澄清更多@Neodan – Naincy

+0

@Neodan謝謝,但是......你實際上可以創建一個以數字開頭的屬性:$ x - > {'1'} = 23; https://3v4l.org/Je7Jl 另外,我第二個Naincy的問題:) – konrados

+1

關聯數組有命名鍵這意味着鍵必須是一個字符串。但我認爲問題不在關鍵數據類型中,但您可以創建一個變量來打破變量命名的規則。 – Neodan