2013-03-28 187 views
2
$obj = (object)array('a', 'b', 'c'); 
$refl = new \ReflectionObject($obj); 
$props = $refl->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);  

foreach($props as $prop) 
    print $prop->name; 

打印一些奇怪的名稱,如linefileline(而不是1,2,3)。爲什麼?我意識到名稱是無效的,因爲它們是數字,但爲什麼我會得到這些隨機字符串?奇怪行爲

get_object_vars($obj)說明不了什麼,而實際上print_r((array)$obj)正確打印值。


如果反射無法顯示數字屬性,有什麼辦法可以讓它忽略它們嗎?


它也發生在許多SPL interators(如ArrayObject S,SplFixedArray S,SplHeap S)。顯然,這種行爲只存在於某些PHP 5.3版本中。 PHP 5.4沒有任何顯示。


Related PHP bug和我的作爲在溶液(property_exists忽略無效名稱):

if(version_compare(PHP_VERSION, '5.4') < 0){ 
    $props = array_filter($props, function($prop) use($obj){ 
    return !$prop->isPublic() || property_exists($obj, $prop->name); 
    }); 
} 
+0

什麼ArrayObjects? – sectus 2013-03-28 01:33:17

回答

1

It's a won't fix bug... or strange php behavior。所以,如果你不確定數字鍵的話,你就不能使用對象類型轉換。使用這樣的事情

$obj = new \stdClass(); 
foreach($array as $key=>$value) 
    $obj->{$key} = $value; 

您可以使用從陌生PHP行爲的另一使壞。獲取所有屬性而不反射。

$obj = (object) array('a', 'b', 'c'); 
$obj->{0}='asd'; 
while (list($field, $value) = each($obj)) 
    { 
    var_dump($field, $value); 
    } 

此外,我認爲這個問題只發生在stdClass對象。

+0

它也出現在任何Iterator對象上,比如ArrayObject,SplFixedArray等:( – 2013-03-28 02:35:30

+0

@OneTrickPony,你能打印例子嗎?我的詭計呢? – sectus 2013-03-28 02:45:29

+0

它似乎與我的(數組)解決方案一樣工作。經過多次搜索後,我發現它是5.3中的一個[bug](https://bugs.php.net/bug.php?id=49154) – 2013-03-28 11:50:08

1

鑄造的陣列的一個對象數組鍵入的屬性名稱,以及將值轉換爲它們的值。

你的數組有數字鍵。你的對象有數字屬性。哪些是無效的。

你真的想:

$obj = (object) array('a'=> null, 'b' => null, 'c'=> null);

+0

數字字段名稱是合法的。 '$ obj2 = new \ stdClass(); $ obj2 - > {'0'} ='a';' – sectus 2013-03-28 00:55:01

+0

不在PHP中。這是一個語法錯誤:'$ obj-> 2 =「yey」;'「語法錯誤,意想不到T_LNUMBER,期待T_STRING或T_VARIABLE或‘{’或‘$’」 – Sven 2013-03-28 00:56:35

+0

你的示例不使用整數值作爲屬性名稱。它確實使用了一個帶有數字的字符串。這是不同的。在數組內部,鍵總是整數,而不是字符串。因此,至少在用作屬性名稱時,數值非常成問題。 – Sven 2013-03-28 00:58:36