OHTA412

if文を簡略化する三項演算子、エルビス演算子、Null合体演算子の使い方と注意点

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)falsetrue
float(0.0)false true
string(‘0’)false true
string(”)false true
bool(false)false false
NULLfalse false
array([])false true
array([0])truetrue
未定義変数エラーfalse

エルビス演算子の場合は、if文でfalse判定される値はfalseになります。しかしNull合体演算子の場合は、一見falseになりそうな値もtrue判定される場面が多くあります。未定義の値を条件式に入れると、エルビス演算子の場合はエラーになり、Null合体演算子の場合はfalse判定になります。

どういう値が条件式に入ってくるのかを考慮して、使い分ける必要があります。