Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据PHP版本,获取返回不同结果的\u对象\u变量_Php - Fatal编程技术网

根据PHP版本,获取返回不同结果的\u对象\u变量

根据PHP版本,获取返回不同结果的\u对象\u变量,php,Php,函数实现有时会随着版本的变化而变化,这并不奇怪,但不是像这样。。。看: $array = ["abc","def"]; $object = new stdclass(); foreach($array as $index => $value) { $object->$index = $value; } var_dump(get_object_vars($object)); 对于5.6.x,例如7.0.17和7.1.3,我们得到: array(2) { [0]=> s

函数实现有时会随着版本的变化而变化,这并不奇怪,但不是像这样。。。看:

$array = ["abc","def"];
$object = new stdclass();
foreach($array as $index => $value) {
    $object->$index = $value;
}
var_dump(get_object_vars($object));
对于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" 
} 
演示:

看到了吗?键是整数或字符串,具体取决于版本


为什么??这些变化背后的原因是什么?为什么这没有记录在案?或是吗?

实际上这是一个bug,因为变量必须以字母开头

变量名遵循与PHP中其他标签相同的规则。有效的 变量名以字母或下划线开头,后跟任意 字母、数字或下划线的数量。作为正则表达式, 其表述如下:“[a-zA-Z\ux7F-\xff][a-zA-Z0-9\ux7F-\xff]*”

因此,当您试图设置变量
$object->$index=$value
它必须抛出一个错误(不能像这样设置变量
$1='foo';
$obj->1='foo';

是正确的结果,因为
get\u object\u vars
返回关联数组

返回值»

返回定义的可访问对象的非静态关联数组 范围中指定对象的属性。如果一个属性没有 如果已分配值,则将返回空值


如果您仔细查看3v4.org输出上的版本,它在7.0.0之前(包括7.0.16)和7.1.0之前(包括7.1.2)中被分解。因此,这是7.0中引入的一个bug,并在7.0.17和7.1.3的两个活动版本中及时修复(均于2017年3月16日发布)

查看我们可以看到相关的外观条目:

修复了错误73998(由get#u object_vars创建的数组上存在数组_key_失败)

这将引导我们,并从那里开始:

错误#73998:无法从get#u object_变量访问数值属性

修复方法包括添加检查是否存在数字键,如果存在,则跳过标记为“fast_copy”的块

因此,这是PHP7开发过程中性能优化带来的一个不希望出现的副作用,现在已在所有受支持的版本中修复

有趣的是,Andrea对bug报告进行了评论,认为它与描述一般问题的报告密切相关:

由于数组和对象与底层哈希表类型对它们可以拥有的键类型有不同的限制,因此Zend引擎必须在哈希表之上的一层,在实现数组和对象本身的代码中,强制执行它们的限制。这意味着,如果绕过该代码并直接修改底层哈希表,则数组和对象可能存在无效的内部状态

以及RFC处理的具体案例:

例如,$arr=[0=>1,1=>2,2=>3]$obj=(对象)$arr;生成一个具有名为1和2的不可访问属性的对象,而$obj=新stdClass$obj->{'0'}=1$obj->{'1'}=2$obj->{'2'}=3;生成具有不可访问键“0”、“1”和“2”的数组。使用get_object_vars()时也会出现同样的问题


RFC是在7.2.0中实现的,因为它改变了记录的行为,但是
get\u object\u vars()
的行为实际上是在7.0中的无意更改,因此被实现为一个bug修复程序。

那么你是指它在php7中的bug吗?根据GetObjectVars链接,在PHP5.6中它还应该以字符串形式返回键。你们能澄清更多@neodan关联数组有命名键吗?这意味着键必须是字符串。但我认为问题不在于键数据类型,而是您可以创建一个打破变量命名规则的变量。变量名和属性名不是一回事,因此这不是手册中要查看的相关部分。@IMSoP但您不能声明这样的属性
public$1='foo':)当然可以,但您可以创建一个,如OP的代码所示。这不是个好主意,但实际上并不是禁止的。您可以访问但不能声明其他属性,例如
$foo->{'some-hypenated-phrase'}
。这在JSON或XML解析器中使用,以避免损坏源数据中的名称。谢谢!我相信这就是答案:)
array(2) { 
["0"]=> string(3) "abc" 
["1"]=> string(3) "def" 
}