我试图修改 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(( 返回的非法类型
我该如何修复它?
您正在寻找的内容很容易做到,但是,您需要帮助foreach
一点:
foreach ($it as $b) {
$a = $it->key();
print $a->getN() . ": $b'n";
}
背景:foreach
只能处理整数或字符串的键(有人说标量,我更喜欢数组键类比(,而不能处理数组或对象。
但是,手动获取密钥确实可以毫无问题地工作,有时甚至是PHP内置类所必需的,这些类是迭代器,但返回数组作为键,例如使用MultipleIterator
。
键的类型必须是标量。导致此错误的原因是key
方法返回对象。返回字符串或数值类型,它应该可以工作。
key()
应该返回位置,而不是该位置的元素。如果我们想象我们在数组世界中,假设:返回键,而不是值。
关于key()
的手册说:
返回当前元素的键。
成功时返回标量,失败时返回 NULL。
如果要返回当前位置的元素,请使用current()
:
返回当前元素。
可以返回任何类型。
更新:很遗憾,您不能将对象用作键。
另一种解决方法:让 current 返回一个包含您的键和值的数组...
function current() {
return array($this->key, $this->val);
}
。然后在循环中解压缩数组:
foreach ($iterator as $key_and_value) {
list($key, $value) = $key_and_value;
}
如果您使用 PHP 5.5 或更高版本,它将起作用:
foreach 现在支持非标量键
Foreach 现在支持任何类型的密钥。而非标量键不能 发生在本机PHP数组中,
Iterator::key()
返回任何类型的值,现在将正确处理此值。
http://php.net/manual/de/migration55.new-features.php