我找不到问题中的错误报告,但有趣的是,this commit似乎解决了同一件事:
如果我们在可见私有属性的范围内,则不应该看到私有公共属性。
测试代码写得很好,只需简单的更改,我们就可以在这里使用它:
class Test
{
private $prop = "Test";
function run()
{
return get_object_vars($this);
}
}
class Test2 extends Test
{
public $prop = "Test2";
}
$props = (new Test2)->run();
在var_dump()
上呼叫$props
显示:
array(2) {
["prop"]=>
string(5) "Test2"
["prop"]=>
string(4) "Test"
}
回到您的问题:
PHP怎么可能会提供一个带有两个完全相同的键的数组?谁能解释内部发生的事情,因为在普通的PHP中我无法生成具有两个完全相同的键的数组?
是的,您无法使用带有两个相同键的数组:
var_dump(array_flip(array_flip($props)));
导致:
array(1) {
["prop"]=>
string(4) "Test"
}
但是让我不同意two completely identical keys
,因为这两个具有相同键名的元素不会在哈希表内部存储有相同的键。也就是说,除了潜在的冲突以外,这些都存储为唯一的整数,并且由于这种情况已在内部发生,因此忽略了对用户输入的限制。
,
经过一番弄乱后,看来这并不取决于__sleep()
。
显然,在PHP 7的早期版本中总是如此(但在PHP 5中显然不是)。这个较小的示例显示了相同的行为。
class A {
private $a = 'This is $a from A';
public function showProperties() { return get_object_vars($this); }
}
class B extends A
{
public $a = 'This is $a from B';
}
$b = new B;
var_dump($b->showProperties());
PHP 7.0-7.3的输出
array(2) {
["a"]=>
string(17) "This is $a from B"
["a"]=>
string(17) "This is $a from A"
}
我认为父母中的私人$a
与孩子中的公共$a
是不同的财产。当您更改B
中的可见性时,您并没有更改$a
中A
中的可见性,实际上是在创建一个具有相同名称的新属性。如果您var_dump
对象本身,则可以看到这两个属性。
它应该不会有太大的作用,因为您将无法从子类的父类访问私有属性,即使您可以看到它在早期的PHP 7版本中也存在。
,
我的几分钱。
我不了解同事,但我不相信并认为这是个玩笑。
作为解释-肯定是问题在“ get_object_vars”变量下,因为它返回重复的关联数组。对于同一键,应该是两个不同的哈希表值(这是不可能的,但唯一的解释是)。我找不到与内部get_object_vars()实现的任何链接(即使PHP基于开放源代码,因此也可能以某种方式获取代码和进行调试)。我也正在思考(到目前为止未成功)在内存中查看包含哈希表的数组表示的方法。另一方面,我能够使用PHP的“合法”功能并使用数组做一些技巧。
这是我尝试使用该关联数组测试某些功能的尝试。以下是输出。无需任何解释-您可以看到所有内容并亲自尝试相同的代码,因此只需注释。
-
我的环境是php 7.2.12 x86(32位)-是的,是的,对我感到羞耻
-
我摆脱了“魔术”和序列化,只剩下带来问题的东西。
-
完成了对类A和B以及函数调用的一些重构。
-
A类下的$ key必须是私有的,否则没有奇迹。
-
零件测试变量-除主要问题外没有其他有趣的事情。
-
零件测试copy_vars-重复复制了数组!!新密钥已成功添加。
-
零件测试迭代和new_vars-迭代经历了重复而没有问题,但是新数组不接受重复,接受了最后一个键。
-
测试替换-在第二把钥匙上完成替换,重复入住。
-
测试ksort-数组未更改,重复项未被识别
-
测试分类-更改值并运行分类后,我能够更改顺序并交换重复的键。现在,当我们按键调用数组或分配键时,第一个键变为第二个键,而新键为该键。结果,我能够更改两个键!!在我以为重复键是一种看不见的键之前,现在很明显,当我们引用或分配键时,最后一个键有效。
-
转换为stdClass对象-没办法!仅接受最后一个键!
-
测试未设置-做得好!删除了最后一个键,但是第一个键由负责,只有一个键,没有重复。
-
内部表示测试-这是一个添加其他功能并查看重复项的主题。我现在正在考虑。
结果输出在代码下方。
<?php
class A {
private $key = 'This is $a from A';
protected function funcA() {
$vars = get_object_vars($this);
return $vars;
}
}
class B extends A
{
public $key = 'This is $a from B';
public function funcB() {
return $this->funcA();
}
}
$b = new B();
$vars = $b->funcB();
echo "testing vars:\n\n\n";
var_dump($vars);
var_dump($vars['key']);
var_dump(array_keys($vars));
echo "\n\n\ntesting copy_vars:\n\n\n";
$copy_vars = $vars;
$copy_vars['new_key'] = 'this is a new key';
var_dump($vars);
var_dump($copy_vars);
echo "\n\n\ntesting iteration and new_vars:\n\n\n";
$new_vars = [];
foreach($vars as $key => $val) {
echo "adding '$key','$val'\n";
$new_vars[$key] = $val;
}
var_dump($new_vars);
echo "\n\n\ntesting replace key (for copy):\n\n\n";
var_dump($copy_vars);
$copy_vars['key'] = 'new key';
var_dump($copy_vars);
echo "\n\n\ntesting key sort (for copy):\n\n\n";
var_dump($copy_vars);
ksort($copy_vars);
var_dump($copy_vars);
echo "\n\n\ntesting asort (for copy):\n\n\n";
$copy_vars['key'] = "A - first";
var_dump($copy_vars);
asort($copy_vars);
var_dump($copy_vars);
$copy_vars['key'] = "Z - last";
var_dump($copy_vars);
echo "\n\n\ntesting object conversion (for copy):\n\n\n";
var_dump($copy_vars);
$object = json_decode(json_encode($copy_vars),FALSE);
var_dump($object);
echo "\n\n\ntesting unset (for copy):\n\n\n";
var_dump($copy_vars);
unset($copy_vars['key']);
var_dump($copy_vars);
echo "\n\n\ntesting inernal representation:\n\n\n";
debug_zval_dump($vars);
现在输出:
testing vars:
array(2) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(17) "This is $a from A"
}
string(17) "This is $a from A"
array(2) {
[0]=>
string(3) "key"
[1]=>
string(3) "key"
}
testing copy_vars:
array(2) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(17) "This is $a from A"
}
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(17) "This is $a from A"
["new_key"]=>
string(17) "this is a new key"
}
testing iteration and new_vars:
adding 'key','This is $a from B'
adding 'key','This is $a from A'
array(1) {
["key"]=>
string(17) "This is $a from A"
}
testing replace key (for copy):
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(17) "This is $a from A"
["new_key"]=>
string(17) "this is a new key"
}
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(7) "new key"
["new_key"]=>
string(17) "this is a new key"
}
testing key sort (for copy):
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(7) "new key"
["new_key"]=>
string(17) "this is a new key"
}
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(7) "new key"
["new_key"]=>
string(17) "this is a new key"
}
testing asort (for copy):
array(3) {
["key"]=>
string(17) "This is $a from B"
["key"]=>
string(9) "A - first"
["new_key"]=>
string(17) "this is a new key"
}
array(3) {
["key"]=>
string(9) "A - first"
["key"]=>
string(17) "This is $a from B"
["new_key"]=>
string(17) "this is a new key"
}
array(3) {
["key"]=>
string(9) "A - first"
["key"]=>
string(8) "Z - last"
["new_key"]=>
string(17) "this is a new key"
}
testing object conversion (for copy):
array(3) {
["key"]=>
string(9) "A - first"
["key"]=>
string(8) "Z - last"
["new_key"]=>
string(17) "this is a new key"
}
object(stdClass)#2 (2) {
["key"]=>
string(8) "Z - last"
["new_key"]=>
string(17) "this is a new key"
}
testing unset (for copy):
array(3) {
["key"]=>
string(9) "A - first"
["key"]=>
string(8) "Z - last"
["new_key"]=>
string(17) "this is a new key"
}
array(2) {
["key"]=>
string(9) "A - first"
["new_key"]=>
string(17) "this is a new key"
}
testing inernal representation:
array(2) refcount(2){
["key"]=>
string(17) "This is $a from B" refcount(2)
["key"]=>
string(17) "This is $a from A" refcount(4)
}
本文链接:https://www.f2er.com/3157041.html