2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PHP 初心者向け】 `(null || "") . ("a" || "")` は `"1"`

Posted at

え? どこから 1 が出てきたんですか? 意味が分からないのですが……

落ち着いてください、解説しますよ。

この記事の要点

  • PHP では ?? の代わりに || を使うべきではない
  • 必要であれば ?: を使っても良い(※後述)

論理演算子と暗黙の型変換

  • 論理演算の結果は必ず bool (true または false)
  • オペランドは bool に暗黙的に変換される

となります。このため、

  • null および ""false に暗黙的に変換される
  • "a"true に暗黙的に変換される

となります。従って、 (null || "") . ("a" || "")false . true となります。

文字列結合演算子と暗黙の型変換

  • 文字列結合の際、オペランドは string に暗黙的に型変換される

となります。このため、

  • true"1" に暗黙的に変換される
  • false"" に暗黙的に変換される

となります。従って、 false . true"1" となります。

isset 判定の有無について

また ?? には isset 判定も含まれていますので、その意味でも ||?: では代用できません。

?: (エルビス演算子)

Null 合体演算子 (??) では、左辺が null の場合のデフォルト値を指定することができました。では、左辺値が falsy な値である場合のデフォルト値を指定したい場合はどうすれば良いのでしょうか。

PHP において、その場合は ?: (エルビス演算子) というのを使うといいようです。

$a = 10;
print($a ?: "\$a is falsy");  // => 10

$b = "";
print($b ?: "\$b is falsy");  // => $b is falsy
(null ?: "") . ("a" ?: "")  // => "a"

(余談)このような誤ったコードを書いてしまった経緯の説明

  • JavaScript では ?: のような意味で || を使うことがあった
    • 古い JavaScript では ?? という演算子が存在しなかったため
  • そのため、PHP でもそのように書いてしまった
  • PHP に ?? という演算子が存在するかどうかを調べるのが面倒だった ←本音

2. イディオムっぽい使い道「条件分岐の省略」
論理演算子はしばしば 条件分岐の省略 の為に使われます。

  • ただし TypeScript で strict-boolean-expressions 等が指定されている場合はそのような使い方はできないし、型を無視した表現のため、現在ではどちらにせよ ?? の代わりに JavaScript の || を積極的に使うべきではない
    • しかし、論理演算子の左辺のみがとなる書き方は使用できる
App.tsx
// tsx (TypeScript)
{
  // && の右辺は boolean ではない
  isMyComponentVisible === true && (
    <div>
      <MyComponent />
    </div>
  )
}
2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?