使用PHP 5.5.9并给定此示例测试类:
class Test
implements Iterator
{
private $ar = [ 1, 2, 3 ];
public function toArray() {
return $this->ar;
}
public function rewind() {
reset( $this->ar );
}
public function valid() {
return !is_null( $this->key() );
}
public function key() {
return key( $this->ar );
}
public function current() {
return current( $this->ar );
}
public function next() {
next( $this->ar );
}
}
并执行此示例测试:
$t = new Test;
foreach( $t as $key => $value ) {
echo "orig: $key: $valuen";
// work on the immediate method result
foreach( $t->toArray() as $copyKey => $copyValue ) {
echo " copy: $copyKey: $copyValuen";
}
echo "----n";
}
我得到以下结果:
orig: 0: 1
copy: 0: 1
copy: 1: 2
copy: 2: 3
----
似乎内部foreach
循环正在对Test
的内部成员$ar
进行引用并推进其内部指针,当我期望$t->toArray()
给我一个Test
的内部成员$ar
的副本。
由于我的理解是php总是复制数组,肯定从方法返回时,我期望以下结果:
orig: 0: 1
copy: 0: 1
copy: 1: 2
copy: 2: 3
----
orig: 1: 2
copy: 0: 1
copy: 1: 2
copy: 2: 3
----
orig: 2: 3
copy: 0: 1
copy: 1: 2
copy: 2: 3
----
当我在内部foreach
循环之前进行明确的数组副本时,请使用:
// store method result in variable first
$a = $t->toArray();
foreach( $a as $copyKey => $copyValue ) { /* etc. */ }
或将toArray()
方法更改为:
public function toArray() {
$copy = $this->ar; // this alone won't work
reset( $copy ); // this is what is needed to do the trick
return $copy;
}
i do 获得预期的结果。
这里发生了什么?这是预期的行为吗?我在这里俯瞰着重要的东西吗?
显然,这种行为消失在php 7.0.0中:
https://3v4l.org/l96fw
v5.x中的数组的删除:
$t = new Test;
foreach( $t as $key => $value ) {
echo "orig: $key: $valuen";
$a = $t->toArray(); // copy of array happens under `=` sign
foreach( $a as $copyKey => $copyValue ) {
echo " copy: $copyKey: $copyValuen";
}
echo "----n";
}