PHPの参照(リファレンス)(2)~内部処理に触れる~

LINEで送る
Pocket

今回の記事は、PHPの参照についてのまとめ第2弾。
変数を値渡しする場合と参照渡しする場合について、内部的にはどのような処理をしているのかを見ていく。

PHPのバージョン: 7.1.4

変数の値渡し

コード

実行結果

string(1) “a”
string(3) “abc”

このとき、次のことが行われている。

順序 手順 内部処理
1 $aに”a”を代入する。 $aに”a”を保持するためのメモリー領域が確保される。
2 $bに$aを代入する。 $bを、$aが割り当てられているポインターに紐づける。($b分のメモリー領域は確保されていない。)
3 $bに”abc”を代入する。 $bに”abc”を保持するためのメモリー領域が確保される。

この手順2の時点では、$bは$aのポインターを参照しているだけである。
そして手順3で$bに値が代入されるときに、$bにもメモリー領域が確保される。
このような仕組みをCopy-On-Write (COW)という。

手順3を終えた時点で、$aと$bそれぞれにメモリー領域が割り当てられ、そのメモリー領域がデータを保持している。

値をコピーする場合

変数と値がメモリーでどのように扱われているかを、簡略化して見ていく。

手順1: $a = “a”;

ポインター 変数
1  a  $a
2

手順2: $b = $a;

ポインター 変数
1 a $a, $b
2

手順3: $b = “abc”;

ポインター 変数
1 a $a
2 abc $b

手順3では、$bは「is_ref」という論理値(ブール値)によって、通常の変数か参照かを判断している。
$bは通常の変数であるため、新たにメモリー領域が用意され、値”abc”を持っている。

変数の参照渡し

コード

実行結果

string(3) “abc”
string(3) “abc”

このとき、次のことが行われている。

順序 手順 内部処理
1 $aに”a”を代入する。 $aに”a”を保持するためのメモリー領域が確保される。
2 $bに$aに対する参照を代入する。 $bを、$aが割り当てられているポインターに紐づける。($b分のメモリー領域は確保されていない。)
3 $bに”abc”を代入する。 $bの紐づけられているポインターのメモリー領域に”abc”を保持する。

この手順2と3では、$aと$bそれぞれが同じポインターに紐づけられている。
そのため、$aと$bは同じ値を持つことになる。

参照をコピーする場合

変数と値がメモリーでどのように扱われているかを、簡略化して見ていく。

手順1: $a = “a”;

ポインター 変数
1 a $a
2

手順2: $b =& $a;

ポインター 変数
1 abc $a, $b
2

手順3: $b = “abc”;

ポインター 変数
1 abc $a, $b
2

手順3では、$bは「is_ref」という論理値(ブール値)によって、通常の変数か参照かを判断している。
$bは参照であるため、ポインター1の値は値”abc”に上書きされる。

LINEで送る
Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*