こんにちは!ライターのmuramatsuです。
みなさんは数ある演算子の中でも三項演算子を使用したことはありますか?
三項演算子を使用すると、if文より簡潔に条件文を記述することができて、コードもスッキリになるとっても便利です。
この記事では、
- 三項演算子とは
- 三項演算子の使い方
- 三項演算子の注意点
という基本的な内容から、
- 三項演算子をネストした使い方
- 三項演算子を省略したエルビス演算子とNULL合体演算子
- 三項演算子で検査関数を使用する方法
- if文との速度比較
などの応用的な使い方に関しても解説していきます。
今回はそんな三項演算子について、わかりやすく解説します!
三項演算子とは
三項演算子とは、1つの演算子処理で3つの式を使用するための比較処理です。
三項演算子は以下のように記述します。
基本構文
条件式 ? 真の式 : 偽の式
はじめに条件式を評価し、式の結果がTRUEの場合は真の式を返し、結果がFALSEの場合は偽の式を返します。
条件式がTRUEの場合に真を返し、FALSEの時は偽を返すので、if (if~else)文に似た処理をしてくれることから条件演算子とも呼ばれています。
また条件式にはif文同様に比較演算子を使用したり、boolの真偽値で判断することができます。
if文との違いとしては、if〜else文のように条件によって処理が分岐するのではなく、結果によって真の式、偽の式を返します。
if文についての詳細は下記記事で解説しているので、if文がまだイマイチわからない、という方はぜひ参考にしてみてくださいね。
比較演算子については以下の記事で詳しく解説しています!
三項演算子の使い方
三項演算子の基本的な使い方
ここでは、三項演算子の基本的な使い方を見ていきましょう。
三項演算子を使って変数$num1と$num2の値を比較する簡単な書き方です。
※ここでは変数に値を代入していないので、実行結果は省略します。
<?php $num1 > $num2 ? 'num1はnum2より大きい' : 'num1はnum2より小さい'; ?>
はじめに条件式$num1 > $num2を記述し、?の後に真の式‘num1はnum2より大きい’と偽の式‘num1はnum2より小さい’を書くだけとなります。
この値を比較する書き方は、if~else文でも以下のように記述することができます。
<?php if ($num1 > $num2) { echo 'num1はnum2より大きい'; } else { echo 'num1はnum2より小さい'; } ?>
いかがですか?
if文よりも三項演算子を使った方が1文でスッキリしたコードになるのがわかりますね。
また、三項演算子の結果は変数に代入することもできます。
サンプルプログラム1
<?php $num1 = 100; $num2 = 200; $ans = $value1 < $value2 ? 'num1はnum2より大きい' : 'num1はnum2より小さい'; echo $ans; ?>
実行結果
num1はnum2より小さい
変数$ansに三項演算子の結果を代入して、echoでその結果を出力しています。
また、以下のように三項演算子をメソッドの返り値として使用することもできます。
サンプルプログラム2
<?php function foo($val){ return $value1 < $value2 ? 'num1はnum2より大きい' : 'num1はnum2より小さい'; } $num1 = 100; $num2 = 200; //関数の呼出し $ans = foo($num1, $num2); echo $ans; ?>
実行結果:
num1はnum2より小さい
自分で関数が定義できるfunction関数でfoo関数を作ります。
foo関数の中の返り値(return)の後に三項演算子を記述し、三項演算子の結果を返すようにしています。
三項演算子の注意点
三項演算子は、式の中で返り値を持たないechoを使用するとエラーとなりますので注意しましょう。
以下のように三項演算子の式の中にechoを記述して実行すると、構文解析エラーのParse error: syntax errorが発生してしまいます。
syntaxエラーは大抵入力ミスが原因で発生することの多いエラーです。
<?php $ans = $value1 < $value2 ? echo 'value2' : echo 'value2'; ?>
実行結果
PHP Parse error: syntax error, unexpected 'echo'
そのため、三項演算子の中で結果を出力したい場合は、戻り値があるprintを使用します。
$ans = $value1 < $value2 ? print 'value2' : print 'value2';
三項演算子はif文に比べて記述量が少なくて済むというメリットがありますが、デメリットとして多用すると可読性が下がってしまうこともあります。
三項演算子をネストする
三項演算子の中に三項演算子を重ねてネストすることも可能です。
ネストする場合は下記のように記述します。
基本構文
(条件式1 ? 真の式1 : (条件式2 ? 真の式2 : 偽の式));
はじめに条件式1で真か偽かをみて、TRUEの場合は真の式1が返されます。
FALSEの場合は次の条件式2に移り、その結果によって真の式2または偽の式が返されます。
では実際にジャンケン勝負をするサンプルコードで実装して見ましょう。
サンプルプログラム
<?php $you = 'パー'; $game = ($you == 'グー' ? 'あいこ!' : ($you == 'パー' ? 'あなたの勝ち!' : 'あなたの負け!')); echo 'この勝負、'.$game; echo '<br>'; ?>
この勝負、あなたの勝ち!
ジャンケン勝負で自分(あなた)とコンピュータが勝負をします。
変数$youが自分だとした時、ここではジャンケンの「パー」を出すとして、変数$youにパーを代入します。
コンピューターが「グー」を出す場合、三項演算子の初めの条件式$you == ‘グー’ ?では変数$youがグーだった場合、TRUEになり「あいこ」となります。
FALSEの場合は次の条件式$you == ‘パー’ ? に移ります。
$you == ‘パー’ ?の条件式で、もし変数$youがパーの場合はTRUE「あなたの勝ち!」となり、それ以外(チョキ)の場合はFALSE「あなたの負け!」となります。
変数$gameに三項演算子の結果を代入し、echoで出力しました。
「パー」を出していたあなたは、コンピュータに勝ちましたね。
エルビス演算子とNull合体演算子
PHP5.3から使えるようになったエルビス演算子とPHP7から使えるようになったNull合体演算子は、三項演算子を簡略化したものとなります。
エルビス演算子とは
エルビス演算子は条件式と真の式が同等の時に、三項演算子の「条件式 ? 真の式 : 偽の式」を省略して記述した形のことを呼びます。
実際に日本の公式サイトではエルビス演算子とは呼ばれておらず、三項演算子の1つの書き方として載っています。
基本構文
条件式(真の式) ?: 偽の式;
条件式がTUREと同等だった場合その値または「1」が返され、FALSEだった場合に偽の式が返されます。
では実際のサンプルプログラムで見てみましょう。
1つ目は、変数$aの値が「0」かそうでないかを確認するプログラムです。
サンプルプログラム1
<?php $a = 0; $num = $a ?: '0'; echo $num; ?>
実行結果
0
変数$aの値が「0」なので、$numに代入されたエルビス演算子の結果がFALSEで偽の式「0」が出力されました。
エルビス演算子は値がNULLの場合や、未定義(undefined)の時によく使われることがあります。
2つ目は、変数$aと$bの値の大きさを比べるプログラムです。
サンプルプログラム2
<?php $a = 4; $b = 9; $num = $a < $b ?: 'aはbより大きい値'; echo $num; ?>
実行結果
1
変数$aは$bの値よりも小さいため、TRUEとなり「1」が変数$numに代入され、echoで出力されました。
NULL合体演算子とは
PHP7から使用できるようになったNull合体演算子は、条件式の結果がNULLかそうでないかを返してくれます。
エルビス演算子の場合は変数宣言がされていないとエラーが表示されてしまいますが、Null合体演算子は、指定した変数が存在しない(変数宣言されていない)場合でも、エラーは発生せず値を返してくれます。
基本構文
条件式または$変数 ?? 真の式;
条件式または$変数の値がNULLのとき、真の式が返り、FALSEのときに条件式または$変数の値が返えされます。
では実際に、変数が存在しないときのエルビス演算子とNULL合体演算子の両方の出力結果をみてみましょう。
サンプルプログラム1
<?php //エルビス演算子の場合 echo $check ?: '存在しない'; echo '<br>'; echo '<br>'; //NULL合体演算子の場合 echo $check ?? '存在しない'; ?>
実行結果
Notice: Undefined variable: check in /Applications/XAMPP/xamppfiles/htdocs/testcode.php on line 4 存在しない 存在しない
実行結果を見ると、エルビス演算子の場合はエラーが出ているのに対し、NULL合体演算子の場合は問題なく表示されているのが分かりますね。
では次に、変数宣言がされている場合をみてみましょう。
サンプルプログラム2
<?php $a = 6; $num = $a ?: 'NULL'; echo $num. '<br>'; $b = 0; $num = $b ?: 'NULL'; echo $num. '<br>'; ?>
実行結果
6 NULL
変数$aには値が代入されているので、実行結果はFALSEとなり変数$aの値「6」が表示されました。
一方変数$bの値は「0」になっているので、TRUEとなり真の式’NULL’が表示されました。
三項演算子で検査関数(isset)を使用する
三項演算子の中で、値を比較したりチェックして戻り値のbool型の値を返す関数を使用することも可能です。
以下のサンプルでは、変数がセットされていることを確認するisset関数を、三項演算子の式で使用しています。
サンプルプログラム
<?php $value = NULL; //isset関数で値を確認する $ans = isset($value) ? '値が設定されています。' : '値が設定されていません。'; echo $ans; ?>
実行結果
値が設定されていません。
三項演算子でのisset関数でチェック時には$valueの値がNULLなのでFALSEを返し、偽の式「’値が設定されていません。’」が実行されます。
isset関数の使い方については、以下の記事でも詳しく解説していますので、ぜひ参考にしてください!
三項演算子の速度はどうなの?
三項演算子は、簡単な判定処理ならコードも簡潔に記述できて便利ですが、速度面はどうなのでしょうか?
ここでは、if文による比較処理と三項演算子による比較処理で、どちらがパフォーマンスに優れているか比較してみました。
比較にはmicrotime関数を使用し、ループの中で1000000回判定処理を行い、どちらが早く999999の値と一致させるか比較しています。
サンプルプログラム
<?php // if文による比較 $start1 = microtime(true); for($i = 0; $i < 1000000; $i++){ if ($i == 999999){ print '一致 '; }else{ print ''; } } $end1 = microtime(true) - $start1; echo 'if文 : '.$end1 .'秒'; echo '<br>'; // 三項演算子による比較 $start2 = microtime(true); for($i = 0; $i < 1000000; $i++){ $i == 999999 ? print '一致 ' : print ''; } $end2 = microtime(true) - $start2; echo '三項演算子 : '.$end2 .'秒'; ?>
実行結果
実行結果(1回目) 一致 if文 : 0.0647430419922秒 一致 三項演算子 : 0.0820000171661秒 実行結果(2回目) 一致 if文 : 0.0681941509247秒 一致 三項演算子 : 0.0810210704803秒 実行結果(3回目) 一致 if文 : 0.0677819252014秒 一致 三項演算子 : 0.0872900485992秒
実行結果から、三項演算子よりif文での比較処理のほうが早いことがわかりました!
実行結果を早く取得するか、コードの簡略さを取るかは実際に作るプログラムで使い分けるのがいいでしょう。
まとめ
ここでは、三項演算子を使用した基本的な使い方や注意点、検査関数を三項演算子で使用する方法やif文の速度面での比較などを行いました。
三項演算子は多用すると可読性が下がるデメリットもありますが、条件式を簡潔に記述できますので用途によって使い分けるのが良いでしょう。
もし、三項演算子の使い方を忘れてしまったら、この記事を思い出してくださいね!