【PHP超入門】参照（リファレンス）の代入について

# **はじめに**

この記事を理解するには、変数、関数、クラスの基本的な知識が必要です。
PHP内部で参照の代入がどのように処理されているのか見ていくことで理解を深めることが目的です。
PHPマニュアルでは参照ではなく[リファレンス](http://php.net/manual/ja/language.references.php)という表記をしておりますが、リファレンスより参照と呼ぶ方が多いと思われるため、この記事ではリファレンスではなく参照と記載します。
私はPHPの勉強中で他言語の知識はありません。
おそらくですが、他言語の参照とPHPの参照は異なる部分があるのかと思います。
この記事の参照という言葉は、PHPマニュアルのリファレンスのことを指しています。

この記事は下記の記事の続きになります。

+ [Qiita - 【PHP超入門】値の代入と値渡しについて](http://qiita.com/7968/items/58015344ddab5d5a8b93) by @7968

上記の記事で説明している内容は改めて説明しませんので、最初に上記の記事をご覧ください。

今回、下記の流れでまとめました。

[参照の記述](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E5%8F%82%E7%85%A7%E3%81%AE%E8%A8%98%E8%BF%B0)
[スカラー型の参照代入](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B9%E3%82%AB%E3%83%A9%E3%83%BC%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース1](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B91%E3%82%B9%E3%82%AB%E3%83%A9%E3%83%BC%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース2](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B92%E3%82%B9%E3%82%AB%E3%83%A9%E3%83%BC%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース3](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B93%E3%82%B9%E3%82%AB%E3%83%A9%E3%83%BC%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
[配列型の参照代入](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E9%85%8D%E5%88%97%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース1](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B91%E9%85%8D%E5%88%97%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース2](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B92%E9%85%8D%E5%88%97%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース3](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B93%E9%85%8D%E5%88%97%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
[foreachと参照](http://qiita.com/7968/items/d68a7aaebdc1711f4345#foreach%E3%81%A8%E5%8F%82%E7%85%A7)
　　[サンプルケース1](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B91foreach%E3%81%A8%E5%8F%82%E7%85%A7)
　　[サンプルケース2](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B92foreach%E3%81%A8%E5%8F%82%E7%85%A7)
[オブジェクト型の参照代入](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)
　　[サンプルケース1](http://qiita.com/7968/items/d68a7aaebdc1711f4345#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B91%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%9E%8B%E3%81%AE%E5%8F%82%E7%85%A7%E4%BB%A3%E5%85%A5)

私自身未熟ですので説明に誤りがあるかもしれません。
誤りがあれば、ご指摘ください ((_ _ (´ω｀ )ﾍﾟｺ

# **参照の記述**

変数名の前に `&` を記述すると参照になります。
参照による代入を行うには `$a = &$b` または `$a =& $b` のように記述します。
`&` を `=` の前に記述して `$a &= $b` とした場合は、複合演算子の[ビット演算](http://php.net/manual/ja/language.operators.bitwise.php)の代入になり、参照とは全くの別物です。
`$a &= $b` という記述は `$a = $a & $b` と同義ですので注意してください。

前回の[記事](http://qiita.com/7968/items/58015344ddab5d5a8b93)の値の代入と同様に、スカラー型、配列型、オブジェクト型の参照代入について見ていきましょう。

# **スカラー型の参照代入**

スカラー型（整数型）を参照代入すると、PHP内部ではどのように処理されるのか見ていきましょう。

## **サンプルケース1（スカラー型の参照代入）**

```php:スカラー型（整数型）の参照代入
$a = 1;
$b = &$a;
$b = 2;
echo $a // 結果：2
echo $b // 結果：2
```

2行目で `&$a` と記述していますので `$a` の参照を `$b` に代入しています。
参照代入すると `$a` と `$b` は運命共同体になり、`$a` と `$b` は全く同じ値を指し示します。
`$a` の値を変更すると、同じ値を指し示している `$b` にも影響します。
逆に `$b` の値を変更すると、同じ値を指し示している `$a` にも影響します。

PHP内部ではどのようになっているのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = 1;
```

![ref_assignment_scalar_pt1_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/d9247a70-e9a4-baff-eb74-63cd6e3f746b.png)

`$a` は `(int)1` を指し示します。

### **2行目**

```php:2行目
$b = &$a;
```

![ref_assignment_scalar_pt1_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/b7269012-2675-8700-ff2d-366d9d953ae4.png)

`&$a` と記述することで、参照代入しています。
`$a` と `$b` は運命共同体になるため、全く同じ値を指し示します。
`refcount` は `2` になります。
参照のため `is_ref` は `1` になります。

### **3行目**

```php:3行目
$b = 2;
```

![ref_assignment_scalar_pt1_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/b94e0195-f51c-9960-382b-417fbe38494c.png)

`$b` に `2` を代入しました。
`$b` と `$a` が指し示している値は `(int)2` になります。

最後に `echo` で `$a` と `$b` を表示すると両方とも `2` と表示されます。
1行ずつPHP内部でどのように処理されているのか見ていくことで理解できたかと思います。

もう一つ別のケースを見てみましょう。

## **サンプルケース2（スカラー型の参照代入）**

```php:スカラー型（整数型）の参照代入
$a = 1;
$b = &$a;
$c = &$b;
$c = 2;
$a = 3;
```

2行目で `$b` に `$a` を参照代入しています。
3行目で `$c` に `$b` を参照代入しています。
先ほども説明したとおり、参照代入すると運命共同体になり、全く同じ値を指し示すようになります。
`$a` と `$b` と `$c` は全く同じ値を指し示していると言えます。

PHP内部ではどのようになっているのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = 1;
```

![ref_assignment_scalar_pt2_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/fa7a12a0-7169-a151-b078-0e3b02d32add.png)

`$a` は `(int)1` を指し示します。

### **2行目**

```php:2行目
$b = &$a;
```

![ref_assignment_scalar_pt2_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/a0d63b18-6e01-a575-6b06-9fced3078e55.png)

`&$a` と記述することで、参照代入しています。
`$a` と `$b` は運命共同体になるため、全く同じ値を指し示します。
`refcount` は `2` になります。
参照のため `is_ref` は `1` になります。

### **3行目**

```php:3行目
$c = &$b;
```

![ref_assignment_scalar_pt2_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/94846fe1-627b-712b-3301-25565e4d1a39.png)

`&$b` と記述することで、参照代入しています。
`$b` と `$c` は運命共同体になるため、全く同じ値を指し示します。
`$a` と `$b` はもともと同じ値を指し示していたので、`$a` と `$b` と `$c` は全く同じ値を指し示します。
`(int)1` の `refcount` は `3` になります。

### **4行目**

```php:4行目
$c = 2;
```

![ref_assignment_scalar_pt2_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/63efa95c-1c5d-f675-ee9c-cb40a2a04e6b.png)

`$c` に `2` を代入しています。
`$a` と `$b` と `$c` が指し示している値は `(int)2` になります。

### **5行目**

```php:5行目
$a = 3;
```

![ref_assignment_scalar_pt2_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/25af0dc4-c38e-cbc4-52e7-ec33eba19ee4.png)

`$a` に `3` を代入しています。
先ほどと同じく、`$a` と `$b` と `$c` が指し示している値は `(int)3` になります。
1行ずつPHP内部でどのように処理されているのか見ていくことで理解できたかと思います。

もう一つ別のケースを見てみましょう。

## **サンプルケース3（スカラー型の参照代入）**

```php:スカラー型（整数型）の参照代入
$a = 1;
$b = $a;
$c = 'Hello';
$d = $c;
$e = &$d;
```

4行目まで普通に値渡しをしています。
5行目で `$e` に `$d` を参照代入しています。
PHP内部ではどのようになっているのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = 1;
```

![ref_assignment_scalar_pt3_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/cfc43121-7b38-2d08-147a-11ccdb67047b.png)

`$a` は `(int)1` を指し示します。

### **2行目**

```php:2行目
$b = $a;
```

![ref_assignment_scalar_pt3_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/6f719504-7468-b18e-7a32-14cb7ea18047.png)

参照代入ではなく、値の代入のため `$a` の値が複製されて `$b` に代入されますが、コピーオンライトのため現時点ではまだ値の複製は行なわれず、同じ値を指し示します。
どちらかの値に変更があった時点で値の複製と書き換えが行われます。

### **3行目**

```php:3行目
$c = 'Hello';
```

![ref_assignment_scalar_pt3_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/dc63102d-dd88-1923-a9e9-9cb3be2ccd63.png)

`$c` は `(string)'Hello'` を指し示します。

### **4行目**

```php:4行目
$d = $c;
```

![ref_assignment_scalar_pt3_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/3afafaa6-e711-d3ff-963e-2f3cd9456bc0.png)

参照代入ではなく、値の代入のため `$c` の値が複製されて `$d` に代入されますが、コピーオンライトのため現時点ではまだ値の複製は行なわれず、同じ値を指し示します。
どちらかの値に変更があった時点で値の複製と書き換えが行われます。

### **5行目**

```php:5行目
$e = &$d;
```

![ref_assignment_scalar_pt3_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/48b4fb60-aac9-7038-d261-9631ff393ef8.png)

`$e` に `$d` を参照代入しています。
`$e` と `$d` は運命共同体になり、全く同じ値を指し示します。

先ほどまで `$d` は `$c` と同じ値を指し示していましたが、参照の代入をしたため `$d` と `$e` は全く同じ値を指し示す必要があります。
つまり、この時点で値の複製が必要になったということです。
値の複製が行われ、`$d` と `$e` は全く同じ値を指し示し、その値の `refcount` は `2` になり、`is_ref` は `1` になります。
それにあわせて `$c` が指し示している値の `refcount` は `1` になります。

今まで値自体に変更があったときに値の複製と書き換えが行われる例だけを見てきましたが、値自体に変更がなくても、参照によって値の複製が必要なときは、それにあわせて値の複製が行われます。

次は配列型の参照代入について見ていきましょう。

# **配列型の参照代入**

配列型を参照代入すると、PHP内部ではどのように処理されるのか見ていきましょう。

## **サンプルケース1（配列型の参照代入）**

```php:配列型の参照代入
$a = 'a';
$b = 'b';
$c = 'c';
$arr = [$a, $b, &$c];
$a = 'd';
$b = 'e';
$c = 'f';
```

このコードは下記の回答からの引用です。

引用元：[phpではarrayは参照型ではないのでしょうか？ある関数にarrayの変数を渡し... - Yahoo!知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11109291456)

最後に `var_dump($arr)` で表示すると下記のようになります。

```php:$arrの表示結果
array(3) {
	[0] => string(1) "a"
	[1] => string(1) "b"
	[2] => &string(1) "f"
}
```

なぜ、このような結果になるのか1行ずつ見ていきましょう。

### **1〜3行目**

```php:1〜3行目
$a = 'a';
$b = 'b';
$c = 'c';
```

![ref_assignment_array_pt1_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/a6f578e7-4a24-c7ba-03f6-6cbdf4381b33.png)

変数名は各値を指し示します。

### **4行目**

```php:4行目
$arr = [$a, $b, &$c];
```

![ref_assignment_array_pt1_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/a162501e-ff7d-af4f-e285-26d222038c63.png)

`$arr` に配列を代入しています。
配列の各値は `$a` と `$b` と `$c` ですが、`$c` だけ参照代入です。
参照代入のため `$c` と `$arr[2]` は運命共同体になり、全く同じ値を指し示します。
`(string)'c'` の `refcount` は `2` になり、`is_ref` は `1` になります。
他の値は現時点で複製する必要がないので、`$a` と `$b` と同じ値を指し示します。
どちらかの値に変更があった時点で値の複製と書き換えが行われます。

### **5〜7行目**

```php:5〜7行目
$a = 'd';
$b = 'e';
$c = 'f';
```

![ref_assignment_array_pt1_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/03304d35-2693-c57c-870c-2864c6154aad.png)

`$a` と `$b` と `$c` に別の値を代入しています。
`$c` と `$arr[2]` は参照で同じ値を指し示しています。
そのため、最終的に `$arr` の配列の値を出力すると下記のようになります。

```php:$arrの表示結果
array(3) {
	[0] => string(1) "a"
	[1] => string(1) "b"
	[2] => &string(1) "f"
}
```

もう一つ別のケースを見てみましょう。

## **サンプルケース2（配列型の参照代入）**

```php:配列型の参照代入
$a = [1,2,3];
$b = &$a;
$a[0] = 'a';
$b[2] = 'c';
```

最後に `var_dump($a)` で表示すると下記のようになります。

```php:$aの表示結果
array(3) {
	[0] => string(1) "a"
	[1] => int(2)
	[2] => string(1) "c"
}
```

なぜ、このような結果になるのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = [1,2,3];
```

![ref_assignment_array_pt2_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/f88e3fee-4ec7-100b-5a81-f7a0c4716ae5.png)

変数名 `$a` は `(array)` を指し示し、配列の各キーは各値を指し示します。

### **2行目**

```php:2行目
$b = &$a;
```

![ref_assignment_array_pt2_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/ce22233c-6551-ba08-acb4-d52c4972b2fb.png)

`$b` に `$a` を参照代入しています。
`$b` と `$a` は運命共同体になり、全く同じ `(array)` を指し示します。
`(array)` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **3行目**

```php:3行目
$a[0] = 'a';
```

![ref_assignment_array_pt2_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/8f81911c-4c06-4974-87fa-17fdb6288876.png)

`$a[0]` に `a` を代入しています。
`$a` の配列キー `0` の値は `(string)'a'` になります。

### **4行目**

```php:4行目
$b[2] = 'c';
```

![ref_assignment_array_pt2_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/5729e371-b2ca-92fb-3b1c-a230c1b98766.png)

`$b` の配列キー `2` の値は `(string)'c'` になります。

`$a` と `$b` は全く同じ `(array)` を指し示しているため、最後に `var_dump($a)` で表示すると下記のようになります。

```php:$aの表示結果
array(3) {
	[0] => string(1) "a"
	[1] => int(2)
	[2] => string(1) "c"
}
```

もう一つ別のケースを見てみましょう。

## **サンプルケース3（配列型の参照代入）**

```php:配列型の参照代入
$a = [1,2,3];
$b = &$a[1];
$c = $a;
$c[0] = 'a';
$c[1] = 'b';
$c[2] = 'c';
```

このコードは下記の記事からの引用です。

引用元：[PHPとかいう糞言語｜いんまのブログ](https://ameblo.jp/nikko-inma/entry-11122429825.html)

最後に `var_dump($a)` で表示すると下記のようになります。

```php:$aの表示結果
array(3) {
	[0] => int(1)
	[1] => &string(1) "b"
	[2] => int(3)
}
```

なぜ、このような結果になるのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = [1,2,3];
```

![ref_assignment_array_pt3_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/ab144267-ff0f-2e6b-062a-95690b7c07a9.png)

変数名 `$a` は `(array)` を指し示し、配列の各キーは各値を指し示します。

### **2行目**

```php:2行目
$b = &$a[1];
```

![ref_assignment_array_pt3_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/0673a68b-df62-2d9b-01df-8ecb7e455de7.png)

`$b` に `$a` の配列キー `1` の値を参照代入しています。
`$b` と `$a[1]` は運命共同体になり、全く同じ値を指し示します。
`(int)2` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **3行目**

```php:3行目
$c = $a;
```

![ref_assignment_array_pt3_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/6ace391d-830a-00ed-d25f-c0051de31535.png)

`$c` に `$a` の配列を代入しています。
配列は複製されて代入されますが、コピーオンライトのため、現時点では配列は複製されず、`$c` は `$a` と同じ `(array)` を指し示します。
変数に別の値を代入したり、配列の値を変更するなど、配列の複製が必要になった時点で、複製されます。

### **4行目**

```php:4行目
$c[0] = 'a';
```

![ref_assignment_array_pt3_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/5b493b33-caa1-c42a-b79a-dc3ea30b2666.png)

`$c` の配列キー `0` に `a` を代入しました。
配列の複製が必要になったため、この時点で配列の複製が行なわれます。
`$a` と `$c` は別々の配列を指し示します。
`$a` が指し示している `(array)` の `refcount` は `1` になります。

配列を複製する前から `(int)2` の `is_ref` は `1` でした。
この値は参照されています。
もともと `(int)2` は参照されており、配列が複製されても、参照なのは変わりません。
`$a[1]` と `$b` と `$c[1]`　は全く同じ `(int)2` を指し示します。
それにあわせて `refcount` が `3` になります。

この行では `$a[2]` と `$c[2]` の値は同じです。
`$c[2]` と `$a[2]` は同じ値ですので、この時点では複製されず、同じ `(int)3` を指し示します。
`(int)3` の `refcount` は `2` になります。
コピーオンライトのため、同じ値を指し示していますが、どちらかの値に変更があった時点で複製されて書き換えが行われます。

### **5・6行目**

```php:5・6行目
$c[1] = 'b';
$c[2] = 'c';
```

![ref_assignment_array_pt3_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/a733c396-4b16-b637-6b7a-df12590788d3.png)

`$c[1]` に `b` を代入しています。
`$c[1]` と `$a[1]` と `$b` が指し示している値は `(string)'b'` になります。
`$c[2]` は `(string)'c'` を指し示すようになります。
それにあわせて `(int)3` の `refcount` が `1` になります。

最後に `var_dump($a)` で表示すると下記のようになります。

```php:$aの表示結果
array(3) {
	[0] => int(1)
	[1] => &string(1) "b"
	[2] => int(3)
}
```

1行ずつ見てきたので、なぜこのような結果になるのか理解できたかと思います。
次は `foreach` と参照について見ていきましょう。

# **foreachと参照**

既に `foreach` については理解しているかもしれませんが、簡単に `foreach` の使い方について説明します。
`foreach` は配列または連想配列のデータを取り出すのに便利な制御構文です。
値のみ取り出したいときは、下記のように記述します。

```php:foreach構文（値のみ取り出す）
foreach(取り出したい配列または連想配列 as 値の仮変数) {

	// ループ内で実行する処理

}
```

配列にある名前を取り出して表示するなら、下記のように記述します。

```php:foreachの記述例
$data = ['佐藤', '鈴木', '高橋'];

foreach($data as $value) {
	echo "名前は {$value} です。";
}
```

配列のキーも取り出したいときは、下記のように記述します。

```php:foreach構文（キーも取り出す）
foreach(取り出したい配列または連想配列 as キーの仮変数 => 値の仮変数) {

	// ループ内で実行する処理

}
```

連想配列にある名前と性別を取り出して表示するなら、下記のように記述します。

```php:foreachの記述例
$data = ['佐藤' => '男', '鈴木' => '女','高橋' => '男'];

foreach($data as $key => $value) {
	echo "{$key} さんの性別は {$value} です。";
}
```

`foreach` の使い方については理解できたかと思います。

基の配列の値を2倍にするような `foreach` を記述してみましょう。

```php:基の配列の値を2倍にしたい
$arr = [1,2,3];
foreach ($arr as $a) {
    $a = $a * 2;
}
var_dump($arr);
```

最後に `var_dump` で `$arr` を出力すると下記のようになります。

```php:$arrの出力
array(3) {
	[0] => int(1)
	[1] => int(2)
	[2] => int(3)
}
```

`foreach` 内で2倍にしても基の配列は変わっていません。
なぜかというと `foreach` の仮変数 `$a` に値を代入しているためです。
`foreach` は配列の値の数だけ繰り返し処理をしますが、最初の処理では `$a = $arr[0]` として仮変数 `$a` に代入していると言えます。
前回の[記事](http://qiita.com/7968/items/58015344ddab5d5a8b93)でも説明していますが、値を代入すると値は複製されて別々の値になります。
そのため、基の `$arr` には変化がありませんでした。
基の `$arr` の配列を値を `foreach` 内で変えるには参照を使う方法があります。

```php:基の配列の値を2倍にする
$arr = [1,2,3];
foreach ($arr as &$a) {
    $a = $a * 2;
}
var_dump($arr);
```

最後に `var_dump` で `$arr` を出力すると下記のようになります。

```php:$arrの出力
array(3) {
	[0] => int(2)
	[1] => int(4)
	[2] => &int(6)
}
```

（参照を使うのは推奨されないやり方のようですが）期待通りの結果になりました。
基の配列の値が変わっているのがわかります。
ただ、`foreach` の仮変数を参照にするときに気をつけるべき点と言いますか、落とし穴があります。
どのような落とし穴があるのか `foreach` と参照を使った例を見ていきましょう。

## **サンプルケース1（foreachと参照）**

```php:foreachと参照
$arr = [1,2,3];
foreach ($arr as &$a) {
    $a = $a * 2;
}
$a = 10;
var_dump($arr);
```

このコードは下記の記事からの引用です。

引用元：[Qiita - 初心者を戒めるPHP　リファレンス(参照)はやめろ](http://qiita.com/tadsan/items/fb496e450fc27c8c4494#%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%E5%8F%82%E7%85%A7%E3%81%AF%E3%82%84%E3%82%81%E3%82%8D) by @tadsan さん

最後に `var_dump($arr)` で表示すると下記のようになります。

```php:$arrの表示結果
array(3) {
	[0] => int(2)
	[1] => int(4)
	[2] => &int(10)
}
```

`foreach` に慣れていない方には `foreach` がどのような処理をしているのかわからないかと思います。
今回の `foreach` は3回ループ処理をしており、仮変数で指定した `$a` を使ってループ処理をしています。
`foreach` を使わずに記述すると下記のようになります。

```php
$arr = [1,2,3];

// foreach の1週目
$a = &$arr[0];
$a = $a * 2;

// foreach の2週目
$a = &$arr[1];
$a = $a * 2;

// foreach の3週目
$a = &$arr[2];
$a = $a * 2;

$a = 10;
var_dump($arr);
```

この記述を見るとわかりますが、`foreach` の仮変数 `$a` はグローバルスコープにあります。
`$a` がグローバルスコープにあるということは `foreach` が終わっても、`$a` は `foreach` が終了した時点の状態を保っているということです。
**`foreach` の仮変数 `$a` はグローバルスコープにあり、`foreach` が終了しても最後の状態を保っている**というのがポイントになりますので、覚えておいてください。

それでは、1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$arr = [1,2,3];
```

![ref_assignment_array_foreach_pt1_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/90e3de4c-babb-775e-99c8-20e4f98e0c75.png)

変数名 `$arr` は `(array)` を指し示し、配列の各キーは各値を指し示します。


### **2行目（foreachの1週目）**

```php:2行目（foreachの1週目）
$a = &$arr[0];
```

![ref_assignment_array_foreach_pt1_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/fcb87d1a-6f95-15ca-8204-c532915ee903.png)

ここからは `foreach` 内の1週目の処理です。
`foreach` の仮変数で記述した `$a` に `$arr[0]` を参照代入しています。
`$a` と `$arr[0]` は運命共同体になり、全く同じ値を指し示します。
`(int)1` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **3行目（foreachの1週目）**

```php:3行目（foreachの1週目）
$a = $a * 2;
```

![ref_assignment_array_foreach_pt1_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/92d5a868-4be2-0412-9b9d-4bf0021e79af.png)

`$a` の値に `$a * 2` の値を代入しています。
`$a` は `1` ですので、`1 * 2` の値が代入されます。
`$a` と `$arr[0]` が指し示す値は `(int)2` になります。

### **4行目（foreachの2週目）**

```php:4行目（foreachの2週目）
$a = &$arr[1];
```

![ref_assignment_array_foreach_pt1_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/3182c865-502f-7088-92d5-ef29af00856b.png)

ここからは、`foreach` 内の2週目の処理です。
`$a` と `$arr[1]` は運命共同体になり、全く同じ値を指し示します。
`(int)2` の `refcount` は `2` になり、`is_ref` は `1` になります。
もともと指し示していた `(int)2` の `refcount` は `1` になり、`is_ref` は `0` になります。

`$a` に対して `$a = &$arr[0]` のあとに `$a = &$arr[1]` と記述しました。
**同じ変数に2回参照代入すると、最後の参照代入のみ有効です。**
そのことは上図からもわかりますが、2回参照代入しても `$arr[0]` と `$arr[1]` と `$a` の3つが全く同じ値を指し示すということはありません。

### **5行目（foreachの2週目）**

```php:5行目（foreachの2週目）
$a = $a * 2;
```

![ref_assignment_array_foreach_pt1_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/0a856629-a578-70db-4f3e-207d28052d1f.png)

`$a` の値に `$a * 2` の値を代入しています。
`$a` は `2` ですので、`2 * 2` の値が代入されます。
`$a` と `$arr[1]` が指し示す値は `(int)4` になります。

### **6行目（foreachの3週目）**

```php:6行目（foreachの3週目）
$a = &$arr[2];
```

![ref_assignment_array_foreach_pt1_6.png](https://qiita-image-store.s3.amazonaws.com/0/72985/be425a1d-4d2a-9800-181e-a4b009bcecaa.png)

ここからは、`foreach` 内の3週目の処理です。
`$a` と `$arr[2]` は運命共同体になり、全く同じ値を指し示します。
`(int)3` の `refcount` は `2` になり、`is_ref` は `1` になります。
もともと指し示していた `(int)4` の `refcount` は `1` になり、`is_ref` は `0` になります。

### **7行目（foreachの3週目）**

```php:7行目（foreachの3週目）
$a = $a * 2;
```

![ref_assignment_array_foreach_pt1_7.png](https://qiita-image-store.s3.amazonaws.com/0/72985/42f2cf26-3eb4-57d5-e81f-15371ed638f7.png)

`$a` の値に `$a * 2` の値を代入しています。
`$a` は `3` ですので、`3 * 2` の値が代入されます。
`$a` と `$arr[2]` が指し示す値は `(int)6` になります。

これで `foreach` の処理は終了です。

### **8行目**

```php:8行目
$a = 10;
```

![ref_assignment_array_foreach_pt1_8.png](https://qiita-image-store.s3.amazonaws.com/0/72985/a98c5af7-05ad-9b49-6cc2-1b52dde669cd.png)

冒頭でも説明しましたが、`foreach` の仮変数 `$a` はグローバルスコープにあります。
`foreach` が終了しても `$a` は最後の状態を保っています。
`$a` と `$arr[2]` は運命共同体で、全く同じ値を指し示しています。
この状態で `$a = 10` としているので、`$a` と `$arr[2]` が指し示している値は `(int)10` になります。

最後に `var_dump($arr)` で表示すると下記のようになります。

```php:$arrの表示結果
array(3) {
	[0] => int(2)
	[1] => int(4)
	[2] => &int(10)
}
```

今回は `foreach` の仮変数 `$a` を参照にしており、`foreach` が終了しても、その後の `$a` の記述にも影響しました。
`foreach` の後に [unset()](http://php.net/manual/ja/function.unset.php) で変数を破棄すれば、その時点で参照ではなくなりますので、その後の記述には影響しません。

```php:unsetで変数を破棄する例
$arr = [1,2,3];
foreach ($arr as &$a) {
    $a = $a * 2;
}
unset($a); // 変数 $a の破棄
$a = 10;
var_dump($arr);
```

最後に `var_dump($arr)` で表示すると下記のようになります。

```php:$arrの表示結果
array(3) {
	[0] => int(2)
	[1] => int(4)
	[2] => int(6)
}
```

`unset($a)` で変数が破棄されて参照ではなくなったので、その後の `$a = 10` は影響しません。
ちなみに、変数が破棄されるのは `unset()` 内に記述した変数のみになります。

```php:unsetで変数を破棄する例
$a = 1;
$b = &$a;
unset($b);
echo $a; // 1
echo $b; // Notice: Undefined variable
```

`$b` に `$a` を参照代入しており、`$a` と `$b` は全く同じ値を指し示していますが、`unset($b)` と記述して変数が破棄されるのは `$b` のみです。
`$a` が破棄されることはありません。
`$a` は破棄されていないため、`echo $a` で `1` と表示されますが、`$b` は破棄されているため、`echo $b` とするとエラーが表示されます。

もう1つ `foreach` と参照のパターンを見てみましょう。

## **サンプルケース2（foreachと参照）**

```php:foreachと参照
$arr = [1,2,3];

foreach ($arr as &$a) {
}
var_dump($arr); // 1回目のvar_dump

foreach ($arr as $a) {
}
var_dump($arr); // 2回目のvar_dump
```

2つの `foreach` がありますが、`foreach` 内では何の処理もしていません。
このコードは下記の記事からの引用です。

引用元：[foreachの＄valueを参照で受けると思わぬバグを引き起こす - ぱせらんメモ](http://d.hatena.ne.jp/pasela/20080527/foreach
)

1回目の `var_dump($arr)` の結果です。

```php:$arrの表示結果（1回目）
array(3) {
	[0] => int(1)
	[1] => int(2)
	[2] => &int(3)
}
```

2回目の `var_dump($arr)` の結果です。

```php:$arrの表示結果（2回目）
array(3) {
	[0] => int(1)
	[1] => int(2)
	[2] => &int(2)
}
```

今回のコードを `foreach` を使わずに記述すると下記のようになります。

```php
$arr = [1,2,3];

// 1回目の foreach の処理
$a = &$arr[0]; // 1週目
$a = &$arr[1]; // 2週目
$a = &$arr[2]; // 3週目

var_dump($arr);

// 2回目の foreach の処理
$a = $arr[0]; // 1週目
$a = $arr[1]; // 2週目
$a = $arr[2]; // 3週目

var_dump($arr);
```

それでは、1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$arr = [1,2,3];
```

![ref_assignment_array_foreach_pt2_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/ebb18e90-0bce-83bc-1579-a283dfaabda1.png)

変数名 `$arr` は `(array)` を指し示し、配列の各キーは各値を指し示します。

### **2行目（最初のforeachの1週目）**

```php:2行目（最初のforeachの1週目）
$a = &$arr[0]; // 1週目
```

![ref_assignment_array_foreach_pt2_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/01f61319-ec4e-3dbb-51e5-6637af9024f7.png)

`$a` に `$arr[0]` を参照代入しています。
`$a` と `$arr[0]` は運命共同体になり、全く同じ値を指し示します。
`(int)1` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **3行目（最初のforeachの2週目）**

```php:3行目（最初のforeachの2週目）
$a = &$arr[1]; // 2週目
```

![ref_assignment_array_foreach_pt2_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/31624dbf-510b-cc96-8457-53e73882d610.png)

`$a` に `$arr[1]` を参照代入しています。
`$a` と `$arr[1]` は運命共同体になり、全く同じ値を指し示します。
`(int)2` の `refcount` は `2` になり、`is_ref` は `1` になります。
それにあわせて `(int)1` の `refcount` は `1` になり、`is_ref` は `0` になります。

### **4行目（最初のforeachの3週目）**

```php:4行目（最初のforeachの3週目）
$a = &$arr[2]; // 3週目
```

![ref_assignment_array_foreach_pt2_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/9933ffc8-6ff1-444f-14df-44da2cba0c7e.png)

`$a` に `$arr[2]` を参照代入しています。
`$a` と `$arr[2]` は運命共同体になり、全く同じ値を指し示します。
`(int)3` の `refcount` は `2` になり、`is_ref` は `1` になります。
それにあわせて `(int)2` の `refcount` は `1` になり、`is_ref` は `0` になります。

これで最初の `foreach` の処理は終了です。
`foreach` 内で値を変更することはしていないので、`foreach` の処理をしても `refcount` と `is_ref` しか変わっていません。
注目すべきは、最後の状態です。
先ほども説明しましたが、`foreach` の仮変数 `$a` は、グローバルスコープにあり、`foreach` が終了しても最後の状態のままです。
`$a` と `$arr[2]` は運命共同体であり、全く同じ値の `(int)3` を指し示しています。
この状態で次の `foreach` の処理がされます。

### **5行目（次のforeachの1週目）**

```php:5行目（次のforeachの1週目）
$a = $arr[0]; // 1週目
```

![ref_assignment_array_foreach_pt2_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/1625822a-af0e-f4e1-2593-2782e23fc33f.png)

`$a` に `$arr[0]` の値を代入しています。
`$arr[0]` の値は `(int1)` ですので、`$a` が指し示している値は `(int)1` になります。

### **6行目（次のforeachの2週目）**

```php:6行目（次のforeachの2週目）
$a = $arr[1]; // 2週目
```

![ref_assignment_array_foreach_pt2_6.png](https://qiita-image-store.s3.amazonaws.com/0/72985/11f67c02-84d7-132f-9b9a-bccaaba42a2a.png)

`$a` に `$arr[1]` の値を代入しています。
`$arr[1]` の値は `(int2)` ですので、`$a` が指し示している値は `(int)2` になります。

### **7行目（次のforeachの3週目）**

```php:7行目（次のforeachの3週目）
$a = $arr[2]; // 3週目
```

![ref_assignment_array_foreach_pt2_7.png](https://qiita-image-store.s3.amazonaws.com/0/72985/e9afe14b-3973-75d8-19f6-d9f021a00e38.png)

`$a` に `$arr[2]` の値を代入しています。
`$arr[2]` の値は `(int2)` ですので、`$a` が指し示している値は `(int)2` になります。

最後に `var_dump($arr)` を表示した結果です。

```php:$arrの表示結果
array(3) {
	[0] => int(1)
	[1] => int(2)
	[2] => &int(2)
}
```

1行ずつ見ていくことで、なぜこのような結果になるのか理解できたかと思います。
`foreach` の仮変数はグローバルスコープにあり、参照した場合は `foreach` が終了した後も影響することに注意してください。
変数を破棄するには `unset` を使うようにしましょう。
そもそも、`foreach` に参照を使うのはあまり推奨されないやり方です。
そのことに関しては最後に参考になる記事を紹介します。

次はオブジェクト型の参照代入について見ていきましょう。

# **オブジェクト型の参照代入**

オブジェクト型を参照代入すると、PHP内部ではどのように処理されるのか見ていきましょう。

## **サンプルケース1（オブジェクト型の参照代入）**

```php:オブジェクト型の参照代入
class foo {
  public $bar = 1;
  public $baz = "a";
}
$a = new foo;
$b = &$a;
$a->bar = 2;
$b->baz = "b";
$c = &$a->bar;
$c = 4;
$d = $b;
$d->bar = 5;
$d = 6;
$e = clone $b;
$e->bar = 7;
```

PHP内部ではどのようになっているのか1行ずつ見ていきましょう。

### **1行目**

```php:1行目
$a = new foo;
```

![ref_assignment_object_pt1_1.png](https://qiita-image-store.s3.amazonaws.com/0/72985/9dcb5c54-925d-c6f8-2af1-2e72b28c371d.png)

`$a` は `(object)foo` を指し示します。
`(object)foo` の各プロパティが各値を指し示します。

### **2行目**

```php:2行目
$b = &$a;
```

![ref_assignment_object_pt1_2.png](https://qiita-image-store.s3.amazonaws.com/0/72985/f1dbcd8b-2e3a-661a-8c3f-9e61a287965f.png)

`$b` に `$a` を参照代入しています。
`$b` と `$a` は運命共同体になり、全く同じオブジェクトを指し示すようになります。
`(object)foo` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **3行目**

```php:3行目
$a->bar = 2;
```

![ref_assignment_object_pt1_3.png](https://qiita-image-store.s3.amazonaws.com/0/72985/21b34d9e-8ab0-a280-acef-4568fab31db8.png)

`$a` のオブジェクトの `bar` プロパティは `(int)2` を指し示すようになります。
それにあわえて `(int)1` の `refcount` は `1` になります。

### **4行目**

```php:4行目
$b->baz = "b";
```

![ref_assignment_object_pt1_4.png](https://qiita-image-store.s3.amazonaws.com/0/72985/fa286220-4f0a-3433-61e0-cd7425bb2572.png)

`$b` のオブジェクトの `baz` プロパティは `(string)'b'` を指し示すようになります。
それにあわえて `(string)'a'` の `refcount` は `1` になります。

### **5行目**

```php:5行目
$c = &$a->bar;
```

![ref_assignment_object_pt1_5.png](https://qiita-image-store.s3.amazonaws.com/0/72985/fbd9eb53-f1a6-bfe7-9b91-0f7f837427b7.png)

`$c` に `$a` が指し示しているオブジェクトの `bar` プロパティの値を参照代入しています。
`$c` と `$a->bar` は運命共同体になり、全く同じ値を指し示すようになります。
`(int)2` の `refcount` は `2` になり、`is_ref` は `1` になります。

### **6行目**

```php:6行目
$c = 4;
```

![ref_assignment_object_pt1_6.png](https://qiita-image-store.s3.amazonaws.com/0/72985/2d9f5a42-05d4-d342-1886-a18555ccf5ef.png)

`$c` が指し示してる値は `(int)4` になります。

### **7行目**

```php:7行目
$d = $b;
```

![ref_assignment_object_pt1_7.png](https://qiita-image-store.s3.amazonaws.com/0/72985/c690f74d-a0d8-bad8-e337-26f960b78378.png)

`$d` に `$b` のオブジェクトを代入しています。
`$d` は `$b` と同じオブジェクトを指し示します。
前回の[記事](http://qiita.com/7968/items/58015344ddab5d5a8b93)でも説明しましたが、オブジェクトの各プロパティの値に変更があっても、オブジェクト自体が複製されることはありません。
オブジェクトを複製するには `clone` キーワードを使う必要があります。
`$d` は `(object)foo` を直接指し示しており、`$d = 1` のように別の値を代入するなど、変数名 `$d` が直接指し示すものに変更があれば、その時点で複製されて書き換えが行なわれます。

### **8行目**

```php:8行目
$d->bar = 5;
```

![ref_assignment_object_pt1_8.png](https://qiita-image-store.s3.amazonaws.com/0/72985/8b7fed24-8b07-c736-326d-cb4e1327a633.png)

`$d` が指し示しているオブジェクトの `bar` プロパティに `5` を代入しています。
`(object)foo` の `bar` プロパティが指し示している値は `5` になります。

### **9行目**

```php:9行目
$d = 6;
```

![ref_assignment_object_pt1_9.png](https://qiita-image-store.s3.amazonaws.com/0/72985/c8ec6112-0d32-936d-dac9-974143756085.png)

`$d` に `6` を代入しています。
`$d` が直接指し示しているものに変更があったので、この時点で複製されて書き換えが行なわれます。
`$d` は `(int)6` を指し示します。
それにあわせて `(object)foo` の `refcount` は `2` になります。

### **10行目**

```php:10行目
$e = clone $b;
```

![ref_assignment_object_pt1_10.png](https://qiita-image-store.s3.amazonaws.com/0/72985/4ae20efc-0470-4c3f-a6aa-8d93b3f7903f.png)

`$b` が指し示しているオブジェクトの複製を `$e` に代入しています。
`$e` は複製したオブジェクトを指し示します。
コピーオンライトのため、各プロパティが指し示している値に変更がなければ、既存の値を指し示します。
そのため、`$e` のオブジェクトの `baz` プロパティは、`$b` のオブジェクトの `baz` プロパティと同じ `(string)'b'` を指し示します。
どちらかの値に変更があった時点で、複製されて書き換えが行なわれます。
ここで注目すべきは、`$e` のオブジェクトの `bar` プロパティです。
`$b` のオブジェクトを複製して、`$e` に代入しましたが、もともと `$b` の `bar` プロパティの値は参照されている状態です。
オブジェクトを複製しても参照の状態は変わりません。
`$a` と `$b` が指し示している `(objcet)foo` の `bar` プロパティと `$c` と `$e` が指し示している `(objcet)foo` の `bar` プロパティの3つは運命共同体であり、全く同じ値を指し示しています。
オブジェクトの複製にあわせて `(int)5` と `(string)'b'` の `refcount` の数も変わります。

### **11行目**

```php:11行目
$e->bar = 7;
```

![ref_assignment_object_pt1_11.png](https://qiita-image-store.s3.amazonaws.com/0/72985/b93b1bf9-0a2d-7d2e-236d-2d6c01209f40.png)

`$e` が指し示している `(object)foo` の `bar` プロパティが指し示している値は `(int)7` になります。
つまり `$a` と `$b` が指し示している `(object)foo` の `bar` プロパティと、`$c` と、`$e` が指し示している `(object)foo` の `bar` プロパティが指し示している値は `(int)7` になるということです。

オブジェクトの参照代入がどのようになるか理解できたかと思います。

# **最後に**

1行ずつPHP内部でどのように処理されているのか見てきたため、参照の代入について理解できたかと思います。
最後に参照について @tadsan さんの記事を抜粋して紹介します。

> **リファレンス** (references, **参照**とも呼ばれる)はPHPの言語仕様の中では珍しく、説明がめんどくさい方の文法です。用語がいっぱい出てきてめんどくさいってことは、 **必要に迫られなければ利用しなくて良い** 文法だってことです。
> 
> 私の持論ですが、 **リファレンス(参照)を利用しないで済むなら避けた方が賢明** です。
> 
> 引用元：[Qiita - PHPのリファレンス(参照&)の傾向と対策、あるいはさよなら](http://qiita.com/tadsan/items/74f992dcc48216b571bd)

今まで見てきたのでわかると思いますが、参照を使ったときの処理は複雑です。
参照はなるべく避けた方が賢明なようです。
参照の注意点については @tadsan さんの記事をご覧ください。

+ [Qiita - 初心者を戒めるPHP](http://qiita.com/tadsan/items/fb496e450fc27c8c4494#%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%E5%8F%82%E7%85%A7%E3%81%AF%E3%82%84%E3%82%81%E3%82%8D)
+ [Qiita - モダンPHPアンチパターン](http://qiita.com/tadsan/items/157969b338fd8b782b21#%E5%8F%82%E7%85%A7%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%87%A6%E7%90%86%E3%81%AF%E5%8A%B9%E7%8E%87%E7%9A%84)
+ [Qiita - PHPのリファレンス(参照&)の傾向と対策、あるいはさよなら](http://qiita.com/tadsan/items/74f992dcc48216b571bd)

意図的に参照は避けるにしても、参照についての理解は必要かと思いましたので、今回記事にまとめました。
参照については、参照代入の他に参照渡しがあります。
参照渡しについては別の記事で説明したいと思います。

# **参考サイト**

この記事を書くにあたり、参考にしたサイトです。
記事内で紹介・引用したサイトは既に記載しているためここでは省略します。
とても参考になりました。ありがとうございます。

+ [How PHP manages variables - entwickler.de](https://entwickler.de/webandphp/how-php-manages-variables-125644.html)
+ [Алгоритм наследования классов на PHP  Компьютерная помощь](https://kp-room.ru/page/nasledovanie-php)
+ [Zoom on PHP objects and classes (PHP 5)](http://jpauli.github.io/2015/03/24/zoom-on-php-objects.html)
+ [メモリ管理 &mdash; PHP Internals Book 日本語訳](http://www.phpinternalsbook-ja.com/zvals/memory_management.html)
+ [PHP5 のオブジェクトに関するよくある間違いとメモリ管理 (コピーオンライト) とオブジェクトの取り扱い - Web/DB プログラミング徹底解説](http://keicode.com/cgi/object-in-php-5.php)
+ [PHPの参照はCのポインタとは別物](http://unskilled.site/php%E3%81%AE%E5%8F%82%E7%85%A7%E3%81%AFc%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%81%A8%E3%81%AF%E5%88%A5%E7%89%A9/)
+ [A Close Look Into PHP Zval - Jiajun Yao](http://blog.jjyao.me/blog/2013/03/17/a-close-look-into-php-zval/)
+ [【PHP7内核剖析】3.4 面向对象-对象的实现 - 程序园](http://www.voidcn.com/article/p-sandrlzr-cn.html)
+ [PHP 参照について 1 | DinnerPHP](http://dphp.jp/language-spec/php-%E5%8F%82%E7%85%A7%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6-1/)
+ [PHP7における内部値の表現―パート1 : PHP5とPHP7のzvalの仕組み | プログラミング | POSTD](http://postd.cc/internal-value-representation-in-php-7-part-1/)
+ [PHP内核探索之变量（2）-理解引用 - ohmygirl - 博客园](http://www.cnblogs.com/ohmygirl/p/4128931.html)
+ [Алгоритм наследования классов на PHP  Компьютерная помощь](https://kp-room.ru/page/nasledovanie-php)
+ [How PHP manages variables - entwickler.de](https://entwickler.de/webandphp/how-php-manages-variables-125644.html)
+ [PHPの参照と関数についてちゃんと勉強してみる。 - 感謝のプログラミング 10000時間](http://blog.codebook-10000.com/entry/20131212/1386857045)
+ [PHPのリファレンス(参照)について、自分なりにかみくだいてみる - 風柳メモ](http://furyu.hatenablog.com/entry/20140924/1411531186)
+ [[PHP] foreach内で参照渡しをしたときに、参照が死なずに残ってしまうのはなぜか - 物欲にまみれたにしふなばし](http://nisihunabasi.mods.jp/blog/?p=209)
+ [PHP foreachでの参照渡しに潜む罠](https://www.slideshare.net/wolf-dog/php-passing-byreferenceinforeach)
+ [Qiita - PHPのforeachで参照渡しをしたいときに気をつけること](http://qiita.com/bunty/items/f192d724a3c714f39c45)
+ [Qiita - PHPのforeachで参照渡しを使ったときの落とし穴](http://qiita.com/ttskch/items/c6d8ea00c57640c52cd8)
+ [Qiita - PHPの参照について](http://qiita.com/mikakane/items/011553b08a69fcf2ed06)
+ [Qiita - phpの参照渡しはメモリを食うって本当？](http://qiita.com/kkam0907/items/836c8977776453746455)
+ [&amp;を使ったときの挙動 -&lt;?php$array = array(1,2,3);var_dump($array);e- PHP | 教えて!goo](https://oshiete.goo.ne.jp/qa/8777447.html)

# note

note でも記事を公開してるので、興味がある方はご覧ください。

・[【初学者向けコードリーディング】 PHP の TODO アプリのコードを一緒に読み解こう](https://note.mu/7968/n/n46a8beb87c93)