7

特定の時点で配列に挿入しようとしています:

$hi = "test";
$var2 = "next";
$arr = array(&$hi);
$arr[] = &$var2; // this works
array_splice($arr, 1, 0, &$var2); // this doesn't

splice を使用して配列に挿入しようとすると失敗し、最初の方法を使用しても失敗しないのはなぜですか?

4

4 に答える 4

7

簡単な答えですが、参照を使用してこの関数を呼び出すことは推奨されておらず、(php 構成によっては) 警告が生成される可能性があることに注意してください。

array_splice($arr, 1, 0, array(&$var2));

方法と理由の答え: 何が起こっているかは非常に微妙です。スプライスを行うと、その位置に参照を挿入したため、実際には $var2 が再割り当てされます。次のコードで確認できます。

<?php
  $hi = "test";
  $var2 = "next";
  $arr = array(&$hi);
  $arr[] = &$var2; // this works
  printf("=== var2 before splice:\n%s\n", var_export($var2, TRUE));
  array_splice($arr, 1, 0, &$var2); // this doesn't
  printf("=== var2 after splice:\n%s\n", var_export($var2, TRUE));
?>

次の結果が得られます。

=== var2 before splice:
'next'
=== var2 after splice:
array (
  0 => 'next',
)

接合前の $var2 は、予想どおり ('next') の文字列であったことに注意してください。ただし、結合後、$var2 は文字列 'next' という 1 つの要素を含む配列に置き換えられています。

原因はドキュメントにあると思います:「置換が配列でない場合、1つに型キャストされます(つまり(配列)$パラメータ)。だから何が起こっているのですか?

  • &$var2 を array にreplacementとして渡しています。
  • 内部的に、php は &$var2 を配列 (&$var2) に変換しています。実際には、$param = array($param) と同等のことを行っている可能性があります。これは、&$var2 が array(&$var2) に設定されることを意味します。これは、参照であり、通常のように $var2 のコピーではないためです。これは、通常は呼び出しの範囲外にある変数に影響を与えています。
  • $var2 のこの新しい値を最後の位置に移動し、2 番目の位置に $var2 のコピーを挿入します。

内部で何が起こっているのか、すべて正確にはわかりませんが、スプライス中に $var が確実に再割り当てされています。3 番目の変数を使用すると、参照として既に存在するものに何かを代入していないため、期待どおりに機能することに注意してください。

<?php
  $hi = "test";
  $var2 = "next";
  $var3 = "last";
  $arr = array(&$hi);
  $arr[] = &$var2; // this works
  array_splice($arr, 1, 0, &$var3);
  printf("=== arr is now\n%s\n", var_export($arr, TRUE));
?>

結果を生成します。

=== arr is now
array (
  0 => 'test',
  1 => 'last',
  2 => 'next',
)
于 2012-07-02T03:43:06.037 に答える
2

最後の引数を配列にする必要があるかもしれません。そうしないと、マニュアルに従って型キャストされます。

array_splice( $arr, 1, 0, array( &$var2 ) ); 
于 2012-07-02T03:30:10.357 に答える
2

あなたのような例を試してみると、「呼び出し時の参照渡しは推奨されていません」という警告が表示されます。この答えによると:

php.ini ファイルで allow_call_time_pass_reference を true に設定できます。しかし、それはハックです。

于 2012-07-02T03:31:59.003 に答える