为什么对象被认为是不可迭代的,尽管它们实际上是可迭代的?

Bjö*_*tau 5 php iterator

PHP 7.1 添加了新的is_iterable函数来检查变量是否可以迭代。但是,尽管您可以迭代对象属性is_iterable,但它们的属性返回 false。

这似乎是故意的,因为它被记录在案,我找不到任何关于该问题的 PHP 错误,但我想知道为什么要这样做?

<?php
$a = new stdClass();
$a->foo = 'bar';

var_dump(is_iterable($a));

foreach ($a as $key => $value) {
    var_dump($key, $value);
}
Run Code Online (Sandbox Code Playgroud)

输出

boolean false
string 'foo' (length=3)
string 'bar' (length=3)
Run Code Online (Sandbox Code Playgroud)

但我希望它输出

boolean true
string 'foo' (length=3)
string 'bar' (length=3)
Run Code Online (Sandbox Code Playgroud)

Nan*_*nne 5

它是一个定义问题,“为什么要这样做”是一个棘手的问题,对 PHP 开发人员来说可能更好。

但是一些信息:你可以在一个对象上 foreach,它会根据手册显示可见的属性

PHP 5 提供了一种定义对象的方法,因此可以遍历项目列表,例如使用 foreach 语句。默认情况下,所有可见属性都将用于迭代。

is_iterable正在检查具体的事情,看手册

验证一个变量的内容是否被 iterable 伪类型接受,即它是一个数组或一个实现 Traversable 的对象

一个对象并没有实现Traversable,如果你不这样做你自己(而不是“他者”的一件事,就像一个数组),因此它不是“迭代”在SENCE。

长话短说:foreach 可以迭代任何可迭代的东西,但并非 foreach 可以迭代的所有东西都称为可迭代的。它的椅子有 4 条腿与 4 条腿的所有东西都是椅子有点问题。

我会看到这样一个事实,即您可以在不显式实现 iterable 的情况下迭代一个对象是一种例外,并将其留在那里。唯一的其他答案是“他们这样做是因为”。

  • 听起来很适合与 PHP 相关的答案……嗯 ¯\\_(ツ)_/¯。 (2认同)
  • @Alex 下一句:*“必须使用`IteratorAggregate` 或`Iterator` 来代替。”*(注意:这两个都是`Traversable` 的子类...) (2认同)