【PHP】"?(クエスチョン)"マークとは?
たかぽん
今回はPHPで出てくる"?"マークについて解説していこうと思います!

あまり頻繁に出るものではないですが、ふと気づいたらそこにある...

そんな"?"マークですが、PHPを扱う上では必ず知っておかないと困るので頑張っていきましょう!

”?”マークとは?

さて、それでは早速"?"の意味をみていきましょう。

Manualによると...

これは”三項演算子”と呼ばれているようですね。

ちなみにマニュアルの使用例は以下。

// 三項演算子の使用例
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];

// 上記は以下の if/else 式と同じです。
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}

PHP マニュアル 三項演算子

前半の$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];が後半のif文と同じ動作をしています。

とはいったものの、ちょっとややこしいですね...

簡単にした例を用意しておきました。

$hoge(三項演算子の前の変数)がtrueの時、直後に続く二つの値のうち、":"(コロン)の前の値が返っています。

つまり、"?(三項演算子)"の直前の値が真なら後に続く二つの値のうち一つ目を返します。

そして、逆に偽だった場合、二つ目の値を返すんです。

それが"?(三項演算子)"の役割です。

実際に上記の例の$hoge = true;$hoge = false;と書き換えて実行してみてください。

そうするときっと、"false desu"が返ってくるはずです。

”?”マークの応用

はい、基本的な働きがわかったところで、少し応用的なことについてお話ししていきたいと思います。

この三項演算子はtrueの場合に返す値が評価する値と一緒でいい場合、省略することができます。

ちょっとややこしいので例をみますね。

ちょっと長いですが、最初は$kekkaだけ追ってみてください。

$kekka = $hoge ?: 'false desu';となっていて、先ほどのコロンの前の値が省略されていますね。

また、$hoge'true desu'という文字列が入ってる場合、その値が出力されているようです。

これは、$hogeの真偽を判定し、その結果によりそのままの値か、あるいはfalseの場合の値を返しています。

え?でも$hogeってboolean型じゃなくてString型なんじゃないの?と思われるかもしれません。

実はPHPでは変数をそのまま突っ込むとそれぞれの値ごとに真偽をつけてくれるんです...!

じゃぁどんな値ならどんな真偽値が返ってくるの?

ということで、簡単に検証した結果が先ほどの長い部分です。

基本的に使いそうなものをある程度網羅して試しています。

例えば空の文字列''が三項演算子(?)の前にあった場合、それは偽と判定されますね。

逆に'hoge'という文字列であればそれは真と判定されています。

つまり、ある変数に文字列が入っていたらその文字列を、そして入っていなければデフォルトでなんらかの値をいれたりできますね。

例えば社員名簿があって、読み仮名を登録してあればその値を出力、されていなければ'未登録です'という文字を出力なんてことができそうですね!

$yomigana = $kanaName ?: '未登録です';

事前に名前の読み仮名が登録されていれば$kanaNameにはその文字列が、スキップされて、入力されていなければ、から文字''がいれられているとすると、上記の一行でそれを判定して名前が未登録の人のカナ名欄にはいい感じに'未登録です'と表示されます。

そんな使い方ができますね!

ちなみに、省略せずに書いた場合はこうなります。

$yomigana = $kanaName ? $kanaName : '未登録です';

”?”マークのネスト

さて、それでは次はネスト(繰り返し適応)についてみていきましょう。

三項演算子はネストすることができます。

さて、ここで、確認しておきたいのですが、

一般的な関数などが計算にあった場合、末端から実行されることが多いです。

`result = 1 + multiple(multiple(2,3),5)`

例えば上記のような計算式があった場合、大抵の方はまずmultiple(2,3)で2*3 = 6が計算されて、その後6*5=30、そして30 + 1で31がresultに入るんだな?

って思うかと...

それに似た感覚で先ほどのネストをみていくと...?

$kekka = $hoge ? $huga : false ? 'true desu' : 'false desu';

先に末端から...つまり、false ? 'true desu' : 'false desu'

が実行されると、答えは'false desu'ですね。

そして次は''false desu'が返ってきたので、$hoge ? $huga : 'false desu'になります。

$hogeは'true'なので、$huga、つまり、trueが返ってきます。

ところが、返ってきているのは先に計算した方でtrueだった場合に返ってくるはずの'true desu'が返ってきてます。

あれ?

そうなんです...実は...三項演算子は...

左から順に実行されます。

つまり、先に$hoge ? $huga : falseが計算され、結果として$hugaが返ってきます。

そして次に$huga ? 'true desu' : 'false desu'が計算され、結果として文字列'true desu'

が返ってくるというわけです。

理解した上でお聞きしますが、難解ですよね...?w

また、仮にどうなるか理解できた今でもパッと出てくると解読に時間がかかるでしょう...

こちら、実はマニュアルでもネストして使用するのは非推奨になっています。

注意:
三項演算子を "積み重ねて" 使用することは避けましょう。 ひとつの文の中で複数の三項演算子を使用した際の PHP の振る舞いは、 少々わかりにくいものです。

PHP マニュアル 三項演算子

なので、どうしても使わないといけないんだけど...っていう場合は一旦冷静になって、別のアプローチがないか探してみましょう!

できればそんな複雑な条件分岐は減らした方が良いのですが、どうしても無理だよ〜っていう場合は分量は増えますが、if文を使って三項演算子を1つに減らすなどすることで可読性を維持できるかもしれません。

ネストして使うと周りのプログラマーから煙たがられるのでほどほどに...

まとめ

はい、というわけで、今回は三項演算子についてがっつり調べてきました!

正直使ったことがない人が初めてみるとまさに”?”となる演算子ですが、うまく使えるようになるとコードの量も減らせるし、よみやすさもぐんと上がります。

機会があればぜひ使ってみてください。(使いすぎて難解にならないように注意!w

それでわ!

おすすめの記事