3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【PHP】if文で「isset()」を使うより「??」を使うべき理由がコレ

Posted at

以前ちょっとだけPHPのチームに所属していた時に、タイトルの通り、__ある変数に値が入っていた場合にのみ、その後の処理を行う__ようにコードを書こうとしていました。

なんてことない処理なのですが、自分が思いつくままに書いたコードはこんな感じでした。

if (isset($someVar)) {
    echo("Uno");
}

そして、そのままプルリクエストを出したのですが、
レビュアーの先輩から「こんな書き方で動かないかな?」というコメントと共にこんなコードを送られました。

if ($someVar ?? "") {
    echo("Uno");
}

それまでPythonしか触ってこなかったので、「ダブルはてな?なにこれ?」となりました笑

この「??」の働きとしては、ざっくり言うと__「??」の前にある変数に値が無い場合には、「??」の後ろにある変数の値に置換する__というものになります。

基本的な使いかたについてはこちらの記事を参考にしていいただくと良いかと思います。

ただ、自分はなぜif ($someVar ?? "")という条件分岐が機能しているのかが当時よく分からなかった上に、
isset()がダメな理由もピンと来ていなかったので、
自分なりにググったり、コードをいろいろ書いてみて理解を試みました。

結果的にそれなりに理屈が分かるようになったので、
今回の記事にはその中で調べたことをまとめておこうと思います!

isset()を使わない理由

この理由自体はシンプルなものでした。

PHPにおいて値が入っているかどうかを調べためには、
isset()の他に、empty()is_null()が使われることが多いようなのですが、
コード全体で、これらが混ざり合ってしまい、可読性が下がるのを避けるためとのことでした。

加えて、値が入っているかの判定を??に揃えることで、
チェックしたい変数に値が入っていなかったときに代入したい値があれば、そのまま代入することも可能なので、
この??を使うようにチーム全体で統一するようにしていたみたいです。

if ($someVar ?? "")がどう機能しているのか

そして本題なのですが、
自分はif ($someVar ?? "")がどう機能しているかが全く分かりませんでした。

もう少し具体的に書くと、
__if ("")(←からの文字列)__という形でコードを見たことがなく、どんな挙動になるのかが見当が付きませんでした。

そこで自分でいろいろと実験をしてみました。

まずは下記のコード。

$someVar = null;
echo($someVar ?? "Uno");

if ($someVar ?? "Uno") {
    echo("Dos");
}

1行目で$someVarという変数にnullを設定
2行目で$someVar ?? "Uno"を出力することで、後の4行目のif文に渡るデータを確認
4行目の$someVar ?? "Uno"の結果、5行目の処理が走るかを確認

結果としては、UnoDosという文字列が出力されました。

つまり、4行目ではif("Uno")がチェックされ、
Trueが返ってきていたようです。

なぜifの中に文字列が入ることでifの中の処理が走るのか全く理解できず小一時間ほどググり続けていたのですが、
実はifに文字列というのは自分が別の形でずっとやってたことと同じだったんです笑

というのも、自分が普段使っているPythonで下記の様なコードを書くことはあったのですが、
ちゃんと考えれば、何かしらの値(厳密に言ったら違いますが、)が変数に入っていればifの中の処理が走るというのはどの言語でも同じことでした。

var = request.GET.get('param')
if var: 
    print('var has some value in it') 
# request.GET.get('param')で値が取れた場合
#    >>> var : paramに設定された文字列
# とれなかった場合
#    >>> var : None (ifの中身が実行されない)

こんな感じで「リストが空の時は~」みたいなことは今まで何百回も書いていたのですが、
こうやって整理してみることで、改めて基礎の勉強になりました。

#まとめ

  • 変数に値が入っているかどうかで条件分岐をする時には、isset()よりも??を使ってコード全体でそろえる方がベター(好みにはよりますが、)
  • if文で空文字はfalse判定になる。なにかしらの文字を含んでいればtrue判定になる。
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?