【问题标题】:Is there are way to foreach on object which class implements Iterator in PHP?有没有办法在对象上 foreach 哪个类在 PHP 中实现 Iterator?
【发布时间】:2012-05-21 08:38:52
【问题描述】:

我尝试修改 php.net 中的示例以尝试实现类似 Java/C# 的集合,其中键可能是对象(http://php.net/manual/en/language.oop5.iterations.php,示例 # 2):

<?php
class Test {
        private $_n;
        public function __construct($n) {
              $this->_n = $n;  
        }
        public function getN() {
                return $this->_n;
        }
}
class MyIterator implements Iterator
{
    private $var = array();

   // code from php.net ....

    public function key() 
    {
        $var = key($this->var);
        echo "key: $var\n";

        return new Test($var);
    }

    // code from php.net...

}

$values = array(1,2,3);
$it = new MyIterator($values);

foreach ($it as $a => $b) {
    print $a->getN() . ": $b\n";
}

但我有这样的通知:

警告:MyIterator::key() 返回非法类型

我该如何解决?

【问题讨论】:

标签: php iterator


【解决方案1】:

您正在寻找的东西很容易做到,但是您需要帮助foreach一点:

foreach ($it as $b) {
    $a = $it->key();
    print $a->getN() . ": $b\n";
}

背景:foreach 只能处理整数或字符串的键(有人说是标量,我更喜欢数组键的类比),不能处理数组或对象。

然而,手动获取密钥确实没有问题,有时甚至对于作为迭代器但返回数组作为密钥的 PHP 内置类for example with MultipleIterator 时甚至是必要的。

【讨论】:

  • 是的,我已经这样做了,但我很遗憾在 PHP 中完全实现是不可能的
  • 哦,我亲爱的小宝贝,我能感觉到你。但是 PHP 不是一门舒适的语言,如果你需要在语法和使用上更优秀的东西,我强烈推荐 scala。
【解决方案2】:

键的类型必须是一个标量。该错误是因为您的 key 方法正在返回一个对象而引起的。返回字符串或数字类型,它应该可以工作。

【讨论】:

  • 我的问题是如何返回一个对象。
  • 答案是“不在key()
  • C# 和 Java 可以遍历键是对象的集合。如何在 PHP 中做到这一点?
  • @GuyFawkes 你不能,就这么简单。您唯一能做的就是将对象序列化为字符串并将其用作键,但您最好重新考虑您的策略。 C# 和 Java 可以做到这一点,并不意味着 PHP 必须这样做。
  • 这个答案是错误的。可以将数组和对象作为键返回,foreach 的用法有限,但处理起来很容易,see my answer
【解决方案3】:

key() 应该返回位置,而不是该位置的元素。如果我们想象我们在数组世界中,假设:返回键,而不是值。

key() 上的手册说:

返回当前元素的键。

成功时返回标量,失败时返回 NULL。

如果要返回当前位置的元素,请使用current()

返回当前元素。

可以返回任何类型。

更新:很遗憾,您不能将对象用作键。

【讨论】:

  • 我想返回的不是位置的元素(例如,对于 index === 0,它将是 1),而是一个对象。
  • @GuyFawkes 你不想在key() 中这样做。阅读手册。你需要的是current()
  • 当前不是我需要的。阅读问题。我需要实现类似 C# 的集合,其中键可以是对象。
  • @GuyFawkes 你从来没有在你的问题中提到过这个。如果你这样做了,我早就告诉你,你不能这样做。请编辑您的问题。
  • 我编辑问题。 PHP不能进入对象键是非常糟糕的。
【解决方案4】:

另一种解决方法:让当前返回一个包含您的键和值的数组...

function current() {
    return array($this->key, $this->val);
}

...然后在循环中解压缩数组:

foreach ($iterator as $key_and_value) {
    list($key, $value) = $key_and_value;
}

【讨论】:

    【解决方案5】:

    如果您使用 PHP 5.5 或更高版本,它将工作:

    foreach 现在支持非标量键

    foreach 现在支持任何类型的键。虽然非标量键不能 发生在原生 PHP 数组中,Iterator::key() 可能 返回任何类型的值,现在可以正确处理。

    http://php.net/manual/de/migration55.new-features.php

    【讨论】:

      猜你喜欢
      • 2012-04-15
      • 2014-11-24
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多