Spl, ArrayObject, ArrayObject::STD_PROP_LIST

35

我正在尝试理解文档中的STD_PROP_LIST常量,但是到目前为止我还没有理解它,也没有找到任何说明 :(

文档中提供了以下示例:

$a = new ArrayObject(array(), ArrayObject::STD_PROP_LIST);
$a['arr'] = 'array data';                             
$a->prop = 'prop data';                               
$b = new ArrayObject();                                   
$b['arr'] = 'array data';                             
$b->prop = 'prop data';                               

// ArrayObject Object                                     
// (                                                      
//      [prop] => prop data                               
// )                                                      
print_r($a);                                              

// ArrayObject Object                                     
// (                                                      
//      [arr] => array data                               
// )                                                      
print_r($b);

两个打印结果完全相同:

ArrayObject Object ( [prop] => prop data [storage:ArrayObject:private] => Array ( [arr] =>      array data ) ) 
ArrayObject Object ( [prop] => prop data [storage:ArrayObject:private] => Array ( [arr] => array data ) )

有人能帮我理解使用这个常量和不使用它之间的区别吗?

先行致谢!

2个回答

99

ArrayObjectArrayIterator 这两个类非常相似,它们在 PHP 核心内部实际上共享了很多代码。这两个类都有一个内部数组,用于存储您设置到这些类中的元素。

STD_PROP_LIST 告诉我们如何读取,ARRAY_AS_PROPS 则告诉我们如何写入这些元素。首先,使用标准数组([])符号来设置元素始终以相同的方式工作,不管是否设置了这些选项。

当设置了 ARRAY_AS_PROPS 标志时,这意味着当您设置属性(通过 ->)时,它不会像常规对象一样被设置在对象上,而是将其存储为内部元素。如果没有设置此标志,它将把属性存储到实际的数组对象或数组迭代器中,这就是您在示例代码输出中看到的 "prop => propdata" 不在 storage:ArrayObject:private 中的原因,如果设置了 ARRAY_AS_PROPS 标志则会出现这种情况:

$a = new ArrayObject();
$a['arr'] = 'array data';
$a->prop = 'prop data';

$b = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$b['arr'] = 'array data';
$b->prop = 'prop data';

print_r($a);
print_r($b);

// Output:
ArrayObject Object
(
    [prop] => prop data
    [storage:ArrayObject:private] => Array
        (
            [arr] => array data
        )
)
ArrayObject Object
(
    [storage:ArrayObject:private] => Array
        (
            [arr] => array data
            [prop] => prop data
        )
)

STD_PROP_LIST 决定在特定条件下返回什么,最明显的是在 var_dump() 中。虽然还有其他情况,但我自己没有发现它们。如果设置了 STD_PROP_LIST,它将返回已设置到您的 ArrayObjectArrayIterator 类上的属性。如果未设置,则 var_dump() 将返回已存储的内部元素列表。

实际文档对于 STD_PROP_LIST 不是 100% 正确。该标志影响 var_dump(),但不影响 foreach()。使用 foreach() 时,它总是迭代内部元素,从不迭代实际属性,即使已设置 STD_PROP_LIST

这两个标志不是互斥的:您可以设置两个标志,但这样做没有多大意义:它意味着属性始终作为内部元素添加(ARRAY_AS_PROPS),并且我们想通过 var_dump 返回标准属性(STD_PROP_LIST)。由于属性不能被设置,因此在这种情况下始终返回空列表。


15
你应该将这个答案放在 PHP 文档的评论中,因为它对 ArrayObject 标志有很多澄清作用。即使在文档中我也没有找到这种类型的解释。非常感谢! - Rowinson Gallego
这真的很令人困惑,但这是我找到的最好的解释。 - djule5

1

@JayTaph提供的答案非常好,但print_r更像是一个调试函数。实际上在使用数组时,例如在foreach中,两者之间的差异变得很明显:

$a = new ArrayObject();
$a['arr'] = 'array data';
$a->prop = 'prop data';

$b = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$b['arr'] = 'array data';
$b->prop = 'prop data';

echo "\$a:<br>\n";
foreach( $a as $key=> $value) {
  printf( "[%s] : %s<br>\n", $key, $value);
}

echo "\$b:<br>\n";
foreach ($b as $key => $value) {
  printf("[%s] : %s<br>\n", $key, $value);
}

将输出:

$a:
[arr] : array data
$b:
[arr] : array data
[prop] : prop data

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接