「0」は、1文字を含む文字列として、直感的には空ではありません。他のプログラミング言語とは異なり、PHPはブール値に変換されたときにFALSEとして処理するのはなぜですか?
'0'
として扱われる0
中$x + 1
、なぜそれとしても扱われるべきではない0
、したがってfalse
、でif ( $x )
?
「0」は、1文字を含む文字列として、直感的には空ではありません。他のプログラミング言語とは異なり、PHPはブール値に変換されたときにFALSEとして処理するのはなぜですか?
'0'
として扱われる0
中$x + 1
、なぜそれとしても扱われるべきではない0
、したがってfalse
、でif ( $x )
?
回答:
PHPは、文字列入力(URLパラメーター、またはブラウザー内のフォームからのPOSTリクエスト)を頻繁に処理するWebリクエストで使用するために設計(または、むしろ進化)しました。そのため、文字列を他の型に自動的にキャストします。
この単純な例では、ということです'1' + '2'
与え3
、エラーではなく、または'12
」、または他のいくつかの解釈を。同じロジックにより、文字列'0'
を数値として使用できます0
。
一方、多くの言語と同様に、PHPはブール値にキャストするときに特定の値を「偽」として扱います。これは、直感的に「空」の値です。これには0
、空の文字列''
と空の配列だけでなく、数値も含まれます[]
。if
ステートメント、式は明示的に、ブール値にキャストされたif ( 0 )
と同じですif ( false )
。
これら2つのことをまとめると、難問が生じます。一方で、あなたが言うの'0'
は空でない文字列です。一方、0
「空」の数値として使用できると述べました。PHPは、'0'
「ゼロネス」を「ストリングネス」よりも重要なものとして扱うことを選択しているため、「偽」と見なされます。
要するに:'0' == 0 == false
; または(bool)'0' === (bool)(int)'0'
"0"
偽」の振る舞いを持つPerlから取ったと思います。Perlでは、文字列"0"
と数字の間に文字通りユーザーが目に見える違いはありません0
。JSONを処理するときは迷惑ですが、テキストデータを処理するときは非常に直感的です。その場合0
、文字列も偽でなくて数字を偽にすることは不可能"0"
です。PHPとJavaScriptは、この設計上の決定を借り、それでも暗黙の変換を可能にしながら、文字列/ bools /数値型を区別することによって、いくつかの混乱を追加します(PHP: 、0 == "0 foo"
、0 == false
しかし"0 foo" == true
:==
推移されていません)
eq
。しかし、これは不可逆的なキャストの非推移性からそれを救いません:"0 foo"
ブールコンテキストでは真実ですが、0
under と等しくなり==
ます。だから、if ( ! $foo ) ..
と$false = (1 == 2); if ( $foo == $false ) ...
同じ結果を与えることはありません。私は言語は一貫し、これを扱うことができ、「ブール平等」オペレータ...不足していると思います
$_POST['id'] == 0
などの数値と比較します。これにより、ユーザー入力を数値として扱いたいという意図が明確になります。
$false
には0
;に設定されることです。そのため、を記述したときに$foo == $false
、Perlはブール値の比較が必要であることを知らず、代わりにintにキャストします。PHPでは、$false
ブール値がfalseであるため、これは発生しません。==
ブール値にキャストすると、同じ結果が得られます!
booleanに関するPHPドキュメントによると、次のように書かれています。
ブール値に変換する場合、次の値が考慮され
FALSE
ます...
空の文字列、および文字列 "0"
...
さもないと:
他のすべての値はTRUE(リソースを含む)と見なされます。
実行する場合:
var_dump((bool) "0");
印刷されます:
bool(false)
期待通りに機能しています。
質問に明示的に回答するには:
ただし、ほとんどの場合、キャストは不要です。演算子、関数、または制御構造がブール引数を必要とする場合、値は自動的に変換されるためです。
これは、PHPの「オートキャスト」が「0」を整数0にキャストすることを意味します。これはFALSE
、if()
ステートメントなどの制御構造でも同様です。