11: 演算子

<font color="green"><h1>演算子</h1></font>

<font color="red">演算子（Operator:オペレーター）</font>とは、与えられた変数やリテラルに対して、あらかじめ決められた処理を行うための記号。

右辺の値を左辺の変数に代入するための「=」演算子や、乗算を行うための「*」演算子など。

演算子によって処理される<font color="blue">変数/リテラル</font>のことを<font color="blue">オペランド（Operand:被演算子）</font>と呼ぶ。

<font color="blue">\$x</font><font color="red">=</font><font color="blue">5</font><font color="red">+</font><font color="blue">4</font>
<font color="blue">青: オペランド（被演算子）</font>
<font color="red">赤: オペレーター（演算子）</font>

PHPでは変数/リテラルの比較や文字列/配列の結合、コンピュータ独自のビット処理など、さまざまな処理が用意されている。

PHPで利用可能な演算子は

①代数演算子

②代入演算子

③比較演算子

④論理演算子

⑤ビット演算子

⑥その他の演算子

に分類される。

<font color="pink"><h2>①代数演算子</h2></font>

<font color="red">算術演算子</font>とも言う。
四則演算をはじめ、日常的な数学で利用する演算子を提供する。

主な代数演算子

|演算子|概要|例|
|:-:|:-:|:-:|
|+|数値の和|5+4 →9|
|-|数値の差|6-3 →3|
|*|数値の積|3*4 →12|
|/|数値の商|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`|

代数演算子は見た目にも最もわかりやすく、直感的に利用できるものがほとんどだが、利用に際して注意点もある。

<font color="pink"><h2>文字列混在の演算</h2></font>

代数演算子では、数値だけでなく文字列も演算可能。
なお、文字列混在の演算ルールについてPHP8で大きく変化したので、まずはPHP7.4までの結果から。

```
<?php
print ‘108’ + ‘15’;
①//結果: 123

print ‘108’ + ‘1.5XYZ’;
②//結果: 109.5

print ‘108’ + ‘XYZ10’;
③//結果: 108

print ‘108’ + ‘1.5XYZ10’;
④//結果: 109.5

print ‘108’ + ‘1.5E1’;
⑤//結果: 123

print ‘108’ + ‘0b11’;
⑥//結果: 108

print ‘108’ + ‘010’;
⑦//結果: 118

print ‘108’ + ‘0x1A’;
⑧//結果: 108

```

①はリテラルがクォート文字で囲まれているので、オペランドの108と15はいずれも文字列型の値。
しかし代数演算子はこれを暗黙的に数値リテラルとみなして演算する。

これは文字列と数値とが混在している場合も同様（②〜④）。

まず数値が先頭にくる②のケースでは、後続の不要な文字列を無視して演算する。

つまり108+1.5で結果は109.5となる。

ただし③のように文字列が先頭にくる場合、PHPはこれを認識できない。

後ろに数値文字列があったとしても同様。

‘XYZ10’はそのままゼロとみなされ、演算の結果も108+0で108となる。

④の場合も同様。
‘1.5XYZ10’は文字列の先頭と末尾に数値文字列が含まれるが、認識されるのは先頭の1.5だけ。
末尾の10は無視される。

⑤は数値/文字列混在のケースですが、指数表現とみなせるケース。
この場合指数表現は数値と認識され、108+15で123という結果が得られる。（108+1.5ではない！1.5E1=15）

もっとも、この変換は例外と考えるべき。

⑥〜⑧のように2/8/16進数文字列を渡した場合には、10進数には変換されず、②〜④と同様のルールで演算される。

8進数の’010’も8ではなく、そのまま10と認識されている点に注目。

ここでは加算演算子（+）の例だけを挙げているが、文字列リテラルに対する演算の考え方は、加減乗除いずれの場合も同様。

<font color="pink"><h2>PHP8での挙動</h2></font>

PHP8でも、先頭が数値で始まる文字列（②、④、⑥、⑧）は数値としてみなされるが、より厳しく
「A non-numeric value encountered」
のような警告が発生する。（PHP7.4以前ではNotice）。

一般的に文字列混じりの数値を演算することは誤りであるはずなので、よりあるべき挙動になったといえる。

なお、③のように先頭が数値でない文字列については
「Unsupported operand types: string + string」
のようなエラーとなる。

文字列を無理に0と解釈する、これまでの挙動は大概バグの原因にしかならないはずなので、これも開発者にとっては望ましい変化である。

<font color="pink"><h2>加算子(++)/減算子(—-)</h2></font>

「++」と「--」は、与えられたオペランドに対して1を加算/減算するための演算子。

それぞれ<font color="red">加算子（インクリメント演算子）</font>、<font color="blue">減算子（デクリメント演算子）</font>という。

たとえば次の先はいずれも同じ意味。

```
$x ++;  ↔︎  $x = $x + 1;
$x —-;  ↔︎  $x = $x - 1;
```

加算子/減算子をオペランドの前後いずれに置くかによって、代入の結果が変わる。

例

```
<?php
①
$x = 10;
$y = ++$x;

print $x; //結果: 11
print $y; //結果: 11


②
$i = 10;
$j = $i++;

print $i; //結果: 11
print $j; //結果: 10
```

加算子をオペランドの前方に置くことを<font color="red">前置演算</font>
後方に置くことを<font color="blue">後置演算</font>という。

①のように前置演算を行った場合、加算子は変数`$x`への加算を行ったあとで`$y`への代入を行う。

一方、

②のような後置演算では、加算子は変数 `$j`への代入を行った後、`$i`への加算処理を行う。

前置演算と後置演算をきちんと区別しておかないと、思わぬ演算結果に悩まされることになる。

<font color="pink"><h2>マジカルインクリメント</h2></font>

加算子には面白い機能がある。
それがマジカルインクリメント。

例

```
<?php
$i = ‘Z’;

print ++$i; //結果: AA
print ++$i; //結果: AB


$j = ‘T8’;

print ++$j; //結果: T9
print ++$j; //結果: U0
```

このように、アルファベットと数値が混在した文字列に対して加算子を適用すると、末尾がアルファベットであれば次の文字へ、数値であれば1を加算するという特殊な処理を行う。

末尾の文字がZ(z)または9であった場合には、1つ前の文字に対して、いわゆる桁の繰上げを行う。

英数字混在の連番コードを生成する場合などに便利な機能。

ちなみに、減算子を用いた、いわゆるマジカルデクリメントのような機能はない。

<font color="green">12は浮動小数点数の演算の注意点から</font>