2

興味深い問題に遭遇したとき、私は配列と参照をいじっていました。たとえば、次のコードを使用します。

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

// Set another value via the reference
$ref = array(2);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

複雑すぎることはありません。配列を作成し、配列内の「深い値」への参照を作成します。

ときvar_dump($saved)、結果は私が期待したものではありません! 私は得る:

array(2) {
  [0]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    &array(1) {
      [0]=>
      int(2)
    }
  }
  [1]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    &array(1) {
      [0]=>
      int(2)
    }
  }
}

配列は参照ではなく値でコピーされたと思いました。が両方のスポットで[b]等しいのはなぜですか? array(2)配列をコピーしてその参照を解除するにはどうすればよいですか?

結果を次のようにしたい:

array(2) {
  [0]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    array(1) {
      [0]=>
      int(1)
    }
  }
  [1]=>
  array(2) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    array(1) {
      [0]=>
      int(2)
    }
  }
}

配列のコピー$refまだリンクされているのはなぜですか? 私は基本的に配列の「状態」を保存し、コピーではなく元の参照のみを更新したいと考えています。$testArray

4

2 に答える 2

1

これは予期される動作です。この関数debug_zval_dump()を使用して、実際にインデックスへの refcounter が であることを確認bできます2

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
debug_zval_dump($saved[0]);

// Set another value via the reference
$ref = array(2);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

あなたに与えるもの:

array(2) refcount(3){
  ["a"]=>
  array(0) refcount(1){
  }
  ["b"]=>
  &array(1) refcount(2){
    [0]=>
    long(1) refcount(1)
  }
}

この動作を回避したい場合は、参照を設定解除し、変更する前に新しい参照を取得する必要があります。

// Set everything up
$testArray = array(
    'a' => array(),
    'b' => array()
);

$saved = array();

$ref =& $testArray['b'];

// Set a value via the reference
$ref = array(1);
unset($ref);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?
debug_zval_dump($saved[0]);

$ref =& $testArray['b'];
// Set another value via the reference
$ref = array(2);
unset($ref);

// Save the current array state
$saved[] = $testArray; // This shouldn't be a reference, right?

var_dump($saved);

ただし、これはあくまでも理論上の話です。もちろん、参照をまったく使用しなくても簡単に実行できます。

于 2013-09-16T20:47:22.840 に答える