配列が引数としてメソッドまたは関数に渡されるとき、参照渡しですか?
これについてはどうですか:
$a = array(1,2,3);
$b = $a;
$b
は$a
への参照ですか?
質問の2番目の部分については、(quoting)を示す マニュアルの配列ページ を参照してください。
配列の割り当てには、常に値のコピーが含まれます。参照演算子を使用して、参照によって配列をコピーします。
そして、与えられた例:
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
// $arr1 is still array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>
最初の部分では、確実な最善の方法は試してみることです;-)
次のコード例を検討してください。
function my_func($a) {
$a[] = 30;
}
$arr = array(10, 20);
my_func($arr);
var_dump($arr);
次の出力が得られます。
array
0 => int 10
1 => int 20
これは、関数がパラメーターとして渡された「外部」配列を変更していないことを示します。参照ではなくコピーとして渡されます。
参照渡しする場合は、次のように関数を変更する必要があります。
function my_func(& $a) {
$a[] = 30;
}
そして、出力は次のようになります。
array
0 => int 10
1 => int 20
2 => int 30
今回は、配列が「参照渡し」で渡されたためです。
マニュアルの References Explained セクションを読むことをheしないでください。あなたの質問のいくつかに答えるべきです;-)
最初の質問に関して、配列は、呼び出しているメソッド/関数内で変更されない限り、参照によって渡されます。メソッド/関数内で配列を変更しようとすると、最初にそのコピーが作成され、次にコピーのみが変更されます。これにより、実際には配列ではなく値によって配列が渡されるように見えます。
たとえば、この最初のケースでは、参照によって$ my_arrayを受け入れるように関数を定義していなくても(パラメーター定義で&文字を使用して)、参照によって渡されます(つまり、メモリを浪費しません)不要なコピー)。
function handle_array($my_array) {
// ... read from but do not modify $my_array
print_r($my_array);
// ... $my_array effectively passed by reference since no copy is made
}
ただし、配列を変更すると、最初に配列のコピーが作成されます(より多くのメモリを使用しますが、元の配列は影響を受けません)。
function handle_array($my_array) {
// ... modify $my_array
$my_array[] = "New value";
// ... $my_array effectively passed by value since requires local copy
}
参考までに、これは「遅延コピー」または「コピーオンライト」として知られています。
デフォルトで
オブジェクトの配列は値(配列)で渡されますが、各オブジェクトは参照で渡されます。
<?php
$obj=new stdClass();
$obj->field='world';
$original=array($obj);
function example($hello) {
$hello[0]->field='mundo'; // change will be applied in $original
$hello[1]=new stdClass(); // change will not be applied in $original
$
}
example($original);
var_dump($original);
// array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } }
注:最適化として、関数内で変更されるまで、すべての単一の値が参照として渡されます。変更され、値が参照によって渡された場合、コピーされ、コピーが変更されます。
PHPのメソッドまたは関数に配列が渡される場合、明示的に参照渡しする場合を除き、値で渡されます。
function test(&$array) {
$array['new'] = 'hey';
}
$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);
2番目の質問では、$b
は$a
への参照ではなく、$a
のコピーです。
最初の例と同様に、次を実行することで$a
を参照できます。
$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);
このスレッドは少し古いですが、ここで私が出会ったもの:
このコードを試してください:
$date = new DateTime();
$arr = ['date' => $date];
echo $date->format('Ymd') . '<br>';
mytest($arr);
echo $date->format('Ymd') . '<br>';
function mytest($params = []) {
if (isset($params['date'])) {
$params['date']->add(new DateInterval('P1D'));
}
}
http://codepad.viper-7.com/gwPYMw
$ paramsパラメータ用のアンプはありませんが、それでも$ arr ['date']の値を変更することに注意してください。これは、ここにある他のすべての説明や、今まで考えていたものとは実際には一致しません。
$ params ['date']オブジェクトを複製した場合、2番目に出力される日付は変わりません。文字列に設定しただけでも、出力には影響しません。
答えの1つを拡張するために、参照によって明示的に渡されない限り、多次元配列のサブ配列も値によって渡されます。
<?php
$foo = array( array(1,2,3), 22, 33);
function hello($fooarg) {
$fooarg[0][0] = 99;
}
function world(&$fooarg) {
$fooarg[0][0] = 66;
}
hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value
world($foo);
var_dump($foo); // (original array modified) array passed-by-reference
結果は次のとおりです。
array(3) {
[0]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
[1]=>
int(22)
[2]=>
int(33)
}
array(3) {
[0]=>
array(3) {
[0]=>
int(66)
[1]=>
int(2)
[2]=>
int(3)
}
[1]=>
int(22)
[2]=>
int(33)
}
PHPでは、次のスニペットが示すように、参照によって明示的に渡す場合を除き、配列はデフォルトで値によって関数に渡されます。
$foo = array(11, 22, 33);
function hello($fooarg) {
$fooarg[0] = 99;
}
function world(&$fooarg) {
$fooarg[0] = 66;
}
hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value
world($foo);
var_dump($foo); // (original array modified) array passed-by-reference
出力は次のとおりです。
array(3) {
[0]=>
int(11)
[1]=>
int(22)
[2]=>
int(33)
}
array(3) {
[0]=>
int(66)
[1]=>
int(22)
[2]=>
int(33)
}