web-dev-qa-db-ja.com

文字列を整数と比較すると奇妙な結果が出る

この操作が機能する理由について、私は本当に混乱しています。誰かがそれを説明できますか?

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";
$test2 = "3581169b064f71be1630b321d3ca318f";

if ($test1 == 0)
  echo "Test 1 is Equal!?";
if ($test2 == 0)
  echo "Test 2 is Equal!?";

// Returns: Test 1 is Equal!?

明確にするために、文字列"0"$test変数と比較しようとしています。 0""を(必要なとおりに)囲むことができるコードを修正することはすでに知っています。

これがPHPバグ、サーバーバグ、または何らかの理由で有効な操作であるかどうかと思います。 http://us3.php.net/types.comparisons)によると これは機能しないはずですが機能しました。

編集:ひっくり返します。明らかに、文字列と0の間の緩い比較が真であることを述べています。しかし、私はまだ理由がわかりません。

編集2:質問を修正しましたが、$test2"3581169b064f71be1630b321d3ca318f"の値が機能しないのはなぜですか?

30

PHPマニュアル から:

数値への文字列変換

文字列が数値コンテキストで評価される場合、結果の値と型は次のように決定されます。

文字列に「。」、「e」、または「E」の文字が含まれている場合、その文字列は浮動小数として評価されます。それ以外の場合は、整数として評価されます。

値は文字列の最初の部分によって与えられます。文字列が有効な数値データで始まる場合、これが使用される値になります。それ以外の場合、値は0(ゼロ)になります。有効な数値データは、オプションの符号、それに続く1つ以上の数字(オプションで小数点を含む)、それに続くオプションの指数です。指数は、「e」または「E」とそれに続く1つ以上の数字です。

37
Assaf Lavie

==演算子を使用した型変換

==演算子は、大まかに型付けされた比較です。両方を共通のタイプに変換して比較します。文字列を整数に変換する方法は ここで説明 です。

リンクしたページ はこれと矛盾しないことに注意してください。整数0と文字列"php"==を使用して比較することは真でなければならないことを示している2番目のテーブルを確認します。

何が起こるかというと、文字列は整数に変換され、非数値文字列(数字を含まないか、数字で始まる文字列)は0に変換されます。

数値文字列と非数値文字列

数値で構成される文字列、または数値で始まる文字列は、数値文字列と見なされます。文字列にその番号の後に他の文字がある場合、これらは無視されます。

文字列が数値の一部として解釈できない文字で始まる場合、それは非数値文字列であり、0に変換されます。これは、数値文字列が数字(0-9)で始まる必要があることを意味するものではありません。たとえば、"-1"は数値文字列です。この場合、マイナス記号は数値の一部であるためです。

たとえば、文字列"d85d1d81b25614a3504a3d5601a9cb2e"は数字で始まっていないため、0に変換されます。ただし、2番目の文字列"3581169b064f71be1630b321d3ca318f"は整数3581169に変換されます。そのため、2番目のテストは同じように機能しません。

あなたがすべきこと

あなたはおそらく望みます:

if ($test1 === "0")

ダブルイコールの代わりにトリプルイコールを使用していることに注意してください。これにより、比較するのは数字のゼロのみを含む文字列であり、型変換を防止します。

9
thomasrutter

調査の結果、PHPマニュアルでは数字で始まらない文字列は整数としてキャストすると0に変換されると記載されています).

この意味は:

("php" == 0) === true
("1php" == 0) === false

非常に煩わしく、十分に文書化されていません。型比較ページのコメントの下にありました。

7
$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";

この文字列は「d」で始まりますが、これは有効な数値ではありません。varは0に解決され、test#1はパスします。

$test2 = "3581169b064f71be1630b321d3ca318f";

この文字列は有効な数値である3581169で始まるため、varは0ではないその値に解決されます。したがって、test#2はパスしません。

2
HBR

数値文字列が数値であるかどうかをテストするために、いくつかの変換と比較を使用しています:

$test1="19de6a91d2ca9d91721d82f1bd8102b6";
   echo (float)$test1==$test1; //TRUE
   echo is_float($test1); //FALSE

   //Converting the string to float and then converting it to string and compare will do the trick 
   echo (string)((float)$test1)==(string)$test1; //FALSE


$test2="5.66";
   echo (float)$test2==$test2; //TRUE

   //Testing the numeric string using `is_float` wont give the expected result
   echo is_float($test2); //FALSE

   echo (string)((float)$test2)==(string)$test2; //TRUE
1
Eiad Samman