この記事の要点
- PHPの演算子には「単項演算子」「二項演算子」「三項演算子」の種類がある
- 演算子は種類によって内部的に優先順位が決まっている
- 優先順位が同じ演算子を使う場合、演算子の結合性によって順番が決定する
- 「結合しない」演算子もあるので注意が必要
以前、PHPはどんなプログラミング言語なのか、また記述ルールから副業案件の獲得まで解説していました。
今回は「演算子」について基本から解説します。
PHPにおける演算子には、
- 単項演算子
- 二項演算子
- 三項演算子
の種類があります。
演算子には優先順位が決まっており、種類によって操作の順番が異なります。
また優先順位が同じ演算子を2つ以上同時に使う場合には、結合性によって順位が決定します。
この記事では、PHPの演算子の種類、優先順位や結合性についてご説明します。
目次
PHPの演算子とは?
コンピュータプログラミング言語における演算子とは、計算する際や値の大小を比較する際に使われる記号のことです。
PHPにおける演算子は、1つ以上の値を受け取り、加算や乗算などの操作を行い、まったく別の値を生み出すもののことを指します。
演算子は、受け取る値の数によって3種類に分類することができます。
- 単項演算子
- 二項演算子
- 三項演算子
単項演算子
単項演算子は1個の値だけを受け取るもので、「!」(論理否定演算子)や「++」(加算子)などです。
例:
<?php $a = 5; $a++; echo $a; ?>
実行結果:
6
二項演算子
二項演算子は、2つの値を受け取って操作を行う演算子です。
PHPのほとんどの演算子は、この二項演算子に当たります。
二項演算子の中でも有名なのが算術演算子です。
算術演算子は、学校で習った算数を思い浮かべると分かりやすいでしょう。
算術演算子には以下の6種類があります。
- 「+」を使った加算
- 「ー」を使った減算
- 「*」を使った乗算
- 「/」を使った除算
- 「%」を使った剰余(除算の余りを求める)
- 「**」を使った累乗
除算演算子の結果として返される値は、浮動小数点数となります。
ただし、2つのオペランドが整数型あるいは整数に変換可能な値である場合で、かつ値が割り切れる場合には整数値を返すので注意が必要です。
例:
<?php $a = 5; $b = 3; $c = 5.5; echo ($a + $b)."\n"; echo ($a - $b)."\n"; echo ($c * $b)."\n"; echo ($c / $a)."\n"; echo ($c % $b)."\n"; echo ($a ** $b)."\n"; ?>
実行結果:
8 2 16.5 1.1 2 125
三項演算子
三項演算子は、3つの値を受け取って操作を行う演算子です。
「条件演算子と呼ぶ方が適切である」
と記されています。
三項演算子に当たるのは「?:」の一種類しかありません。
例:
<?php $a = 5; echo ($a > 10) ? "10より大きい" : "10以下"; ?>
実行結果:
10以下
詳しい三項演算子の使い方は、下記の記事で解説しています。
p-055_phpで三項演算子を使いこなそう!読みやすいコードを書くコツも解説 のリンク
演算子には優先順位がある
PHPにおける演算子には優先順位が設定されているため、使用する際には注意が必要です。
演算子の優先順位表
PHPマニュアルによると、演算子には以下のように優先順位が決まっています。
上に行くほど優先順位が高く、下に行くほど優先順位が低いことを表しています。
左の「結合時の評価」については、後述にてご説明します。
結合時の評価 | 演算子 | 追加情報 |
---|---|---|
(n/a) | clone new | clone および new |
right | ** | 算術演算子 |
(n/a) | + - ++ -- ~ (int) (float) (string) (array) (object) (bool) @ | 算術演算子 (単項演算の + と -), 加算子/減算子, ビット演算子, 型の相互変換 そして エラー制御演算子 |
left | instanceof | 型演算子 |
(n/a) | ! | 論理演算子 |
left | * / % | 算術演算子 |
left | + - . | 算術演算子 (二項演算の + と -), 配列演算子 そして 文字列演算子 (PHP 8.0.0 より前のバージョンの.) |
left | <> | ビット演算子 |
left | . | 文字列演算子 (PHP 8.0.0 以降) |
結合しない | < >= | 比較演算子 |
結合しない | == != === !== | 比較演算子 |
left | & | ビット演算子 そして リファレンス |
left | ^ | ビット演算子 |
left | | | ビット演算子 |
left | && | 論理演算子 |
left | || | 論理演算子 |
right | ?? | NULL合体演算子 |
結合しない | ? : | 三項演算子 (PHP 8.0.0 より前のバージョンでは、左結合でした) |
right | = += -= *= **= /= .= %= &= |= ^= <>= ??= | 代入演算子 |
(n/a) | yield from | yield from |
(n/a) | yield | yield |
(n/a) | ||
left | and | 論理演算子 |
left | xor | 論理演算子 |
left | or | 論理演算子 |
PHP公式マニュアルより引用
基本的なルールを理解しよう
論理演算子の優先順位表を見てみると、「+」「-」は「*」「/」「%」より下に記載されています。
これは、「+」「-」が「*」「/」「%」より優先順位が低いことを表しています。
例:
<?php echo (5 + 4 * 8)."\n"; ?>
実行結果:
37
上の例では「+」と「*」の演算子が出てきますが、「*」の優先順位が高いため、内部的に「*」演算子の2つのオペランドが結合します。
つまり、「5 + (4 * 8)」という優先順位が成り立ち、実行結果が表示されるのです。
算数の授業において、加算・減算より乗算・除算の方が優先されると習いますが、PHPにおいては基本的にそのルールが適用されると考えておくとよいでしょう。
同じく算数の授業において、優先順位を変える際には()を用いることも習います。
同様に、PHPで優先順位を変更する場合には()で結合を明記します。
例:
<?php echo ((5 + 4) * 8)."\n"; ?>
実行結果:
72
最初の例と実行結果が異なるものになりました。
これは、「5 + 4」に()を付けることにより、本来であれば優先されるべき「*」よりも「+」が優先され、結果のような表示がされるのです。
演算子の優先順位が分からなくなったら、必ず優先順位表を参照するようにしましょう。
優先順位が等しければ「結合性」で順位が決定する
優先順位が等しい2つの演算子では、順位がどうなるのかを見ていきましょう。
結合性(結合時の評価)とは?
演算子の優先順位が等しい場合には、結合性によって順位が決定します。
たとえば以下の例を見てみましょう。
例:
<?php echo (1 * 3 * 5)."\n"; ?>
実行結果:
15
使用されているのは2つの「*」演算子であり、優先順位は等しい状態です。
「*」を優先順位表で見てみると、結合時の評価は「left」、つまり左結合=左から評価することが決まっています。
上の例では「(1 * 3) * 5」という結合が内部的に行われ、実行結果が表示されます。
一方で、以下のような例も見てみましょう。
例:
<?php $a = $b = $c; ?>
代入演算子「=」は、優先順位表で見てみると「right」つまり右結合されます。
つまり例では、内部的に「$a = ($b = $c)」というグループ分けがなされることになります。
優先順位の評価順を正しく理解しなければ、場合によっては期待しない結果が得られることになるため、注意する必要があります。
結合しない演算子もある!
優先順位表のなかには、結合時の評価に「結合しない」と書かれているものがあります。
これは、文字通り結合しない演算子であり、並べて記述するとPHPでは無効になってしまいます。
例を見てみましょう。
例:
<?php //これはsyntaxエラーになります if ($a < $b < $c) { } ?>
上の例で使われている「<」演算子は、優先順位表によると結合しない演算子です。
そのため、並べて記述するとシンタックスエラーで実行できなくなります。
上の例の演算を実現したいのであれば、以下のように記述します。
例:
<?php //これはsyntaxエラーになりません if ($a < $b && $b < $c) { } ?>
また、以下のような書き方はエラーにはなりません。
例:
<?php //これはsyntaxエラーになりません if ($a <= $b == $c) { } ?>
優先順位表を見てみると、「<」演算子と「==」演算子の優先順位は異なることがわかります。
そのため、上のように記述してもエラーにならないというわけです。
PHPバージョンアップによって結合性は変化する!?
演算子の優先順位は公式マニュアルに規定されていますが、この規定はPHPがバージョンアップされるたびにマイナーチェンジされています。
そのため、「以前は使えていたのに急に使えなくなった・・・!」という記述方法もあり、バージョンアップに対応する際は注意が必要です。
マイナーチェンジされた例の1つ「三項演算子」を見ていきます。以下の例を見てみましょう。
例:
<?php $sample = true ? "a" : true ? "b" : "c"; ?>
上の例は、三項演算子がネストした状態です。
PHP7までのバージョンでは、三項演算子は「左結合」と定義されていました。
そのため、内部的に「(true ? "a" : true) ? "b" : "c"」と結合され、結果は「b」が表示されていました。
しかしPHP8で三項演算子は「結合しない」に定義が変更になりました。
そのため、上の例を実行すると以下のようなエラーが表示されます。
実行結果:
PHP Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`
「2つの三項演算子が使われているが、結合しないので計算できない」というエラーメッセージになります。
エラーを出さないためには、三項演算子を()で順位付けする必要があります。
例:
<?php $sample = (true ? "a" : true) ? "b" : "c"; //または $sample = true ? "a" : (true ? "b" : "c"); ?>
プログラミング言語は、不変なもののように見えてその実、ITの革新に伴い常に変化し続けています。
気づかないうちにバージョンアップがなされ、既存の機能が一切使えなくなることさえありうるものです。
演算子の結合性に関しても、バージョンアップがあった際には常にチェックするようにしましょう。
まとめ
PHPの演算子には単項演算子・二項演算子・三項演算子があり、優先順位があることをご説明しました。
優先順位が同列の場合、結合性によって評価結果が決まります。また演算子はPHPのバージョンによって使い方が変わるため、注意が必要です。
演算子を正しく使いこなし、高いレベルのPHPプログラマーを目指しましょう。
また、PHPの学習に動画を活用するのもおすすめです。
PHP初心者でも、動画を見ながら簡単に問い合わせフォームや掲示板、ログイン画面が作れますので、参考にしてください。