PHPでif文を使う機会は多いので、簡略化した方がコードがすっきりして見やすくなることがあります。そんなときif文の代替としてよく使われる演算子に、三項演算子、エルビス演算子、Null合体演算子があります。
三項演算子
三項演算子は、if文ととても似ています。
「(条件式) ? (trueの場合) : (falseの場合);」というのが基本的な書き方です。「条件式」「trueの場合」「falseの場合」の3つをそれぞれ項といい、3つの項でできているので三項演算子といいます。
// 三項演算子
$name = empty($_GET['name']) ? 'no name' : &_GET['name'];
// if文
if( empty($_GET['name']) ){
$name = 'no name';
}else{
$name = $_GET['name'];
}
この三項演算子とif文は、同じことを意味しています。そのため、条件式に未定義の変数を入れるとエラーになります。
// $nameが未定義の場合、エラーになる
$user_name = $name ? $name : 'no name'; // Notice: Undefined variable: name
$nameに値が入っていればその値を、入っていなければ’no name’を$user_nameに入れようとしてこのようなコードを書いた場合、$nameが未定義のときにエラーになります。
$nameが確実に定義されていて、何かしらの値(空文字可)が入っている場合は上記のコードでも問題ありませんが、そうでない場合はempty()を使います。empty()は、変数が未定義の場合もエラーにならずtrueを返します。そのため、変数が未定義でもエラーになりません。
// $nameが未定義の場合、条件式がtrueになるので'no name'が返される
$user_name = empty($name) ? 'no name' : $name;
// 値がある場合を2項目に持ってきたい場合は、こういう書き方もできる
$user_name = !empty($name) ? $name : 'no name';
エルビス演算子(?:)
エルビス演算子は、三項演算子の2番目の項が省略された演算子です。「?:」がエルビスプレスリーに似ているので、エルビス演算子と呼ばれています。
// 三項演算子
$user_name = $name ? $name : 'no name';
// エルビス演算子
$user_name = $name ?: 'no name';
この三項演算子とエルビス演算子は、同じことを意味しています。条件式がtrueの場合は、その値をそのまま返します。falseの場合は、「?:」より後ろを返します。
三項演算子のところでも書いたように、条件式に未定義の変数を入れた場合エラーになるので、状況を見極めて使う必要があります。
Null合体演算子(??)
Null合体演算子は、エルビス演算子ととても似ています。条件式がisset()と同じ挙動をとるところが違います。
// Null合体演算子
$name = $_GET['name'] ?? 'no name';
// if文
if( isset($_GET['name']) ){
$name = $_GET['name'];
}else{
$name = 'no name';
}
このNull合体演算子とif文は、同じことを意味しています。条件式がisset()でtrueの場合はその値を返し、falseの場合は「??」から後ろを返します。
isset()は「その変数が宣言されていること、そしてnullとは異なること」を検証しています。つまり、nullではない何かがあればtrue、そうでない場合はfalseとなります。そのため、未定義の変数だったとしてもエラーを返すことなくfalseの判定になります。
しかしここで注意が必要なのは、空文字もtrueになることです。他にも、空の配列や「0」もtrueと判定されます。「変数が空の場合、デフォルトの値を入れたい」といった処理を書きたい場合は、思わぬ挙動をとることがあるので注意が必要です。
$name = '';
$user_name = $name ?? 'no name'; // 条件式が空文字なのでtrue判定される
echo $user_name; // $user_nameの中身は空文字なので、何も表示されない
エルビス演算子とNull合体演算子の条件判定の違い
条件式に入れた値によって、エルビス演算子とNull合体演算子の判定の違いを見てみます。
条件式 | 判定結果 | |
---|---|---|
エルビス演算子 | Null合体演算子 | |
int(0) | false | true |
float(0.0) | false | true |
string(‘0’) | false | true |
string(”) | false | true |
bool(false) | false | false |
NULL | false | false |
array([]) | false | true |
array([0]) | true | true |
未定義変数 | エラー | false |
エルビス演算子の場合は、if文でfalse判定される値はfalseになります。しかしNull合体演算子の場合は、一見falseになりそうな値もtrue判定される場面が多くあります。未定義の値を条件式に入れると、エルビス演算子の場合はエラーになり、Null合体演算子の場合はfalse判定になります。
どういう値が条件式に入ってくるのかを考慮して、使い分ける必要があります。