2017-09-01 21 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