嵌套的foreach循环在假定的数组副本上更改了原始数组的内部指针



使用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";
}

相关内容

  • 没有找到相关文章

最新更新