"迭代"一个单一对象或php对象的索引等价物。

8

我能到达目的地,但我想要最美的道路。

我来到这里是为了研究运行返回对象集合的函数的最佳方法,例如$dom->getElementsByTagName()$pdo->query('SELECT itcher FROM scratches'),然后知道它只有一个结果-访问该结果。

我做了一些研究,但我想知道我是否知道所有需要知道的内容。

foreach或任何遍历多个 things 的方式从美学角度看起来很傻,因为我知道只有一个。将其转换为数组感觉像是一个瑕疵,并且我想快速完成我的代码。到目前为止我最喜欢的是$object->{'0'},因为它与$object[0]非常接近,但在某些情况下似乎不起作用。是否有更漂亮的方法?例如,当设置 $key 为 $val 时,foreach($key as $val) 每次迭代时在做什么?我可以自己做吗?

也许我没有正确定义对象的概念,但getElementsByTagName和 mysql 查询返回数组会更有意义吧?为什么它们不这样做呢?


我不确定这是否适用,但我经常使用Doctrine的getSingleResult()和getArrayResult()函数。它们对查询的处理方式对我来说是个谜。 - Jacob
1
有时,使用数据库时不希望一次将整个结果集都取到内存中,但这是返回数组时所必需的。pdo 提供了 fetchAll() 选项。使用数组还需要调用代码等待获取所有结果,而返回可迭代对象则为调用代码提供了更早地开始处理的机会。但我认为数组应该是默认选项,这些特殊情况接口应该是可选的。 - goat
1个回答

3
例如,当使用foreach($key as $val)时,在每次迭代中将$key设置为$val,它到底在做什么?我能否自己这样做?
如果它真的是一个数组,您可以使用reset()获取第一个元素。
如果它是一个迭代器(用于允许foreach访问对象),那么您应该能够使用$object->current()。
我从未真正查看过foreach的底层代码 - 但是reset()和current()似乎类似于foreach在迭代开始时会 '做' 的事情。
不幸的是,您引用的两个示例都是内部类,并且根据文档,内部类(语言或扩展的一部分的类)不遵循相同的规则:
实现此接口的内部(内置)类可以用于foreach结构,并且不需要实现IteratorAggregate或Iterator。
说了这么多,任何返回可以被 foreach 迭代的对象的用户类都应该是 Traversable 类型(也就是 foreach 所需的类型)。因此,我认为 current() 应该按照您所需要的方式工作。请注意,如果该对象实际上是通过实现 IteratorAggregate 而不是 Iterator 来得到迭代器的话,则必须使用 getIterator()->current()
然而,对于您的两个示例,仍然有可能通过使用特定于返回类型的方法来完成。在使用 getElementsByTagName() 的情况下,您可以使用 getElementsByTagName->item(0),而在 PDO 的情况下,您可以使用 query()->fetch()

这让我感觉我对正在发生的事情有了更好的理解。你是说每个写得好的对象通常都有自己获取下一个相关项的方法,对吗?而且没有全局的 PHP 方法来做到这一点的原因是因为对象有独立的需求和存储数据的方法。此外,非常感谢您包含了 DOM 和 PDO 获取数据的方法 - 这让我非常清楚明白。 - c..
1
@StatycAutomatyc 有点像,似乎大多数对象都应该有一种获取第一个项目的方法;但是,当您使用内部对象时,只需要使用特定于对象的方法。您应该能够利用current()来处理任何库/用户代码(即使没有针对该对象的特定方法)。 - Tim Lytle
作为一条注释- current() 在getElementsByTagName上似乎不起作用,因为它是一个未定义的方法。 - c..
@StatycAutomatyc,没错,正如文档所述,内部类不需要实现IteratorAggregateIterator(用户自定义类需要)。因此,您不能指望current()getIterator()->current()内部类上运行。 - Tim Lytle
哦,抱歉,我明白了。一开始不知道在这种情况下 internal 是什么意思。再次感谢你,太棒了。 - c..

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