独習PHP学習メモ（Chapter3-代数演算子・代入演算子）

[PHP8技術者認定初級試験取得](https://www.phpexam.jp/summary/novice8)を目指しており、無事合格できました！

資格試験用に学習した、公式の認定教材である[独習PHP第4版](https://www.amazon.co.jp/dp/4798168491/)の内容を知識定着のためアウトプットした記事です。


:::note info
過去の投稿はこちら
:::

https://qiita.com/mumucochimu/items/1607809dc28dd026df6d

https://qiita.com/mumucochimu/items/316dd9c83bda14fdfaf8

https://qiita.com/mumucochimu/items/a5ddce721847e863d9d3

## 代数演算子（算術演算子）


主な代数演算子は以下です。

| 演算子 | 概要   | 例    |
|:-----:|:-----:|:-----:|
| +     | 和       | 1+2 ⇨  3 |
| -     | 差       | 3-2 ⇨  1 |
| *     | 積       | 1*2 ⇨  2 |
| /     | 商       | 15/3 ⇨ 5 |
| %     | 割った余り　 | 13%3 ⇨ 1 |
| **    | 累乗     | 2**3 ⇨ 8 |
| ++    | 前置加算（代入前に加算） | $x=3; $y=++$x; ⇨ $yは4 |
| ++    | 後置加算（代入後に加算） | $x=3; $y=$x++; ⇨ $yは3 |
| --    | 前置減算（代入前に減算） | $x=3; $y=--$x; ⇨ $yは2 |
| --    | 後置減算（代入後に減算） | $x=3; $y=$x--; ⇨ $yは3 |


### 文字列混在の演算

PHPは文字列型の値も暗黙的に数値とみなして演算してくれますが、意図しない結果になりやすいです。
（実務ではほぼないと思うが）

ただ、「こういう時こういう挙動をする」っていうのを覚えておくと、
実務でも考慮する材料にもなるし、単純に面白いし、でとても好きです。

:::note warn
以下挙動はPHP8での挙動です。
:::

```PHP:文字列型の数値
// 暗黙的に数値とみなす
'100' + '5';   //結果：105
```

```PHP:数値と文字列が混在
// 文字列までの1.5だけを数値とみなして演算する（ただし警告発生）
'100' + '1.5XYZ';  //結果：101.5

// 文字列が先頭に来る場合は数値として認識しない
'100' + 'XYZ10' // 結果：エラーになる

// 先頭の数値のみ認識する（ただし警告発生）
'100' + '1.5XYZ10'  //結果：101.5
```

### 浮動小数点数の演算


```PHP
floor((0.1 + 0.7) * 10)   //結果：7
```

意図する結果としては8ですが、7となります。
上記は10進数の世界では0.1と表している値も、
コンピューターの世界（2進数）では無限循環小数といい0.0001100110011......となることから発生している結果です。

このような場合は任意精度数学関数を利用しましょう。

参考：https://www.php.net/manual/ja/book.bc.php

先ほどの計算を書き直します。

```PHP
$add = bcadd(0.1, 0.7, 1);
$mul = bcmul($add, 10, 1);  // 結果：8
```


### 配列の結合

加算演算子(+)は配列の加算（結合）にも対応しています。

```PHP:式

$array1 = [
  'Apple' => 'Red',
  'Orange' => 'Yellow',
  'Melon' => 'Green',
];

$array1 = [
  'Grape' => 'Purple',
  'Apple' => 'Green',
];

$result = $array1 + $array2;

// 結果

Array (
  [Apple] => Red
  [Orange] => Yellow
  [Melon] => Green
  [Grape] => Purple
)
```

`'Apple' => 'Green'`が結合結果に入っていないですね。
これは、Appleというキーがかぶっているためです。
挙動としては「左の配列に存在しないキーの要素を右の配列から取り出し、左の配列に追加する」
からですね。

配列を結合したい場合はarray_mergeを使うことも多いですが、
array_mergeは同じキーがあれば後のものを上書きするので、場合により使い分けるのがいいのかな、、、。
参考：https://www.php.net/manual/ja/function.array-merge

いずれにしてもしっかり挙動を理解しておきたいところです。

## 代入演算子

主な代入演算子は以下です。

| 演算子 | 概要   | 例    |
|:-----:|:-----:|:-----:|
| =     | 値を代入 | $x = 10; |
| +=    | 左辺と右辺を加算した結果を左辺に代入 | $x = 5; $x += 2; ⇨ 7 |
| -=    | 左辺から右辺を減算した結果を左辺に代入 | $x = 5; $x -= 2; ⇨ 3 |
| *=    | 左辺と右辺を乗算した結果を左辺に代入 | $x = 5; $x *= 2; ⇨ 10 |
| **=   | 左辺を右辺で累乗した結果を左辺に代入 | $x = 5; $x **= 2; ⇨ 25 |
| /=    | 左辺を右辺で累乗した結果を左辺に代入 | $x = 5; $x /= 2; ⇨ 2.5 |
| %=    | 左辺を右辺で乗算した余りを左辺に代入 | $x = 5; $x %= 2; ⇨ 1 |
| .=    | 左辺と右辺を連結した文字列を左辺に代入 | $x = 'Foo'; $x .= 'Bar'; ⇨ 'FooBar' |

### 参照（リファレンス）による代入

=による代入は「値による代入」が基本となる。
変数$xを変数$yに代入して、変数$xの中身が変更されても変数$yに影響がないのは「値による代入」をしているからです。

例えば以下のような挙動になります。

```PHP
$x = 1;
$y = $x;
$x = 5;

print $y  // 結果：1
```

上記の「値による代入」に対して、「参照（リファレンス）による代入」は元の変数に加えた変更が代入された先の変数にも影響が及びます。

例えば、以下のような挙動になります。

```PHP
$x = 1;
$y = &$x; // 参照代入
$x = 5;

print $y  // 結果：5
```

### 分割代入

分割代入とは、配列などを分解し配列の要素を個々の変数に代入するための構文です。

以下が例となります。

```PHP
$data = [1, 2, 3, 4, 5];
[$a, $b, $c, $d, $e] = $data;

print $a;  // 結果：1
print $b;  // 結果：2
print $c;  // 結果：3
print $d;  // 結果：4
print $e;  // 結果：5
```

左辺の要素数が右辺よりも大きい場合には、不足分は無視されます。

今回はここまで。
次も独習PHP学習メモを投稿します！