記事の内容
この記事では、PHPで扱う参照渡しについて説明します。
PHPのバージョンは、7系です。
参照渡しのやり方
PHPでは、「&」をつけることで参照渡しができます。
「参照渡し」では、変数に代入した値の「参照先」を渡します。
「参照先」とはメモリ空間のアドレスのことを指します。
図にすると、以下のようになります。
では、実際の例も見ていきたいと思います。
参照渡しと値渡しの違い
変数
<?php | |
# PHP_EOLは改行コードです | |
# 値渡しの場合 | |
$val_1 = 10; | |
$val_2 = $val_1; | |
$val_1 = 20; | |
echo '$val_1の中身は' . $val_1, PHP_EOL; | |
echo '$val_2の中身は' . $val_2, PHP_EOL; | |
// $val_1の中身は20 | |
// $val_2の中身は10 | |
$val_1 = null; | |
$val_2 = null; | |
# 参照渡しの場合 | |
# $va_1の値を変更すると、$val_2の値も変わります | |
$val_1 = 10; | |
$val_2 = &$val_1; | |
$val_1 = 20; | |
echo '$val_1の中身は' . $val_1, PHP_EOL; | |
echo '$val_2の中身は' . $val_2, PHP_EOL; | |
// $val_1の中身は20 | |
// $val_2の中身は20 |
配列
<?php | |
# 値渡しの場合 | |
$val_1 = array(1, 2, 3); | |
$val_2 = $val_1; | |
$val_1[0] = 777; | |
var_dump($val_1); | |
// array(3) { | |
// [0]=> | |
// int(777) | |
// [1]=> | |
// int(2) | |
// [2]=> | |
// int(3) | |
// } | |
var_dump($val_2); | |
// array(3) { | |
// [0]=> | |
// int(1) | |
// [1]=> | |
// int(2) | |
// [2]=> | |
// int(3) | |
// } | |
# 参照渡しの場合 | |
$val_1 = null; | |
$val_2 = null; | |
$val_1 = array(1, 2, 3); | |
$val_2 = &$val_1; | |
$val_1[0] = 777; | |
var_dump($val_1); | |
// array(3) { | |
// [0]=> | |
// int(777) | |
// [1]=> | |
// int(2) | |
// [2]=> | |
// int(3) | |
// } | |
var_dump($val_2); | |
// array(3) { | |
// [0]=> | |
// int(777) | |
// [1]=> | |
// int(2) | |
// [2]=> | |
// int(3) | |
// } |
foreach
参照渡しをforeachに使うこともできます。
<?php | |
$nums = array(2, 3, 4); | |
foreach ($nums as $value) { | |
$value = $value * 2; | |
} | |
print_r($nums); | |
// Array | |
// ( | |
// [0] => 2 | |
// [1] => 3 | |
// [2] => 4 | |
// ) | |
# 参照渡し | |
foreach ($nums as &$value) { | |
$value = $value * 2; | |
} | |
print_r($nums); | |
unset($value); | |
// Array | |
// ( | |
// [0] => 4 | |
// [1] => 6 | |
// [2] => 8 | |
// ) |
関数
参照渡しを関数に使うこともできます。
<?php | |
# PHP_EOLは改行コードです | |
# 引数を値渡し | |
function increment_1($number) | |
{ | |
return $number = $number + 1; | |
} | |
# 引数を参照渡し | |
function increment_2(&$number) | |
{ | |
return $number = $number + 1; | |
} | |
$val_1 = 1; | |
$val_2 = increment_1($val_1); | |
echo $val_1, PHP_EOL; | |
// 1 | |
echo $val_2, PHP_EOL; | |
// 2 | |
$val_1 = null; | |
$val_2 = null; | |
$val_1 = 1; | |
$val_2 = increment_2($val_1); | |
echo $val_1, PHP_EOL; | |
// 2 | |
echo $val_2, PHP_EOL; | |
// 2 |
オブジェクト
オブジェクトは最初から参照型なので、「&」をつけなくても参照されます。
参照させたくない場合は、「clone」を使います。
<?php | |
# 参照渡し | |
$klass_1 = new stdClass(); | |
$klass_1->val = 1; | |
$klass_2 = $klass_1; | |
$klass_1->val = 2; | |
var_dump($klass_2); | |
// object(stdClass)#1 (1) { | |
// ["val"]=> | |
// int(2) | |
// } | |
# 値渡し | |
$klass_1 = new stdClass(); | |
$klass_1->val = 1; | |
$klass_2 = clone $klass_1; | |
$klass_1->val = 2; | |
var_dump($klass_1); | |
// object(stdClass)#2 (1) { | |
// ["val"]=> | |
// int(2) | |
// } | |
var_dump($klass_2); | |
// object(stdClass)#3 (1) { | |
// ["val"]=> | |
// int(1) | |
// } |