4

いくつかの文字列値を比較しているときに、PHP で奇妙で予期しない動作に遭遇しました。以下の最初の 2 つのステートメントは、false を返すと予想される場合に true を返します。最後のステートメントは、予想どおり false を返します。私は PHP のType Jugglingを認識していますが、ドキュメントから理解しているのは、文字列と整数のような 2 つの異なるデータ型を比較す​​るときに型ジャグリングが発生するということです。以下の例では、両方のリテラルが文字列です。これは、PHP で文字列比較を行っているときに、両方の文字列を調べて整数のように見えるかどうかを確認し、そうであれば両方を整数に型キャストしてから、それらの整数値を比較することを意味します。したがって、私の質問は、この動作がどのような条件下で発生するか、PHP で文字列比較がどのように機能するかです。

var_dump("10" == "10.0000");
var_dump("10" == "+10.");
var_dump("10" == "10 ");

#output
bool(true)
bool(true)
bool(false)

アップデート

したがって、比較の下のババの答えには、何が起こっているのかを理解するのに本当に役立つ数値文字列が含まれています。関数is_numericは、文字列が数値文字列と見なされるかどうかを返します。興味深いことに"10 "、数値文字列とは見なされませんが、数値文字列と見なされます" 10"。PHP ソース コードを掘り下げたところ、is_numeric の実装はis_numeric_string_ex 関数にあると思います。これにより、PHP が文字列を数値文字列として扱うタイミングを正確に知ることができます。

4

3 に答える 3

2

スペースの位置が原因​​でエラーが発生しています。これは true を返します

var_dump("10" == " 10"); // true

したがって、実行する場合

var_dump("10" == "10 "); //false

実際に実行しているのは、文字列として扱われるためです

var_dump("10" == 0); //false

これは、型ジャグリングがこれに変換"10 " される ため0です。これはPHP ドキュメントにあります。

PHPドキュメントから

型ジャグリング後に $a が $b と等しい場合は TRUE。

数値を文字列と比較する場合、または比較に数値文字列が含まれる場合、各文字列は数値に変換され、数値として比較が実行されます。これらの規則は、switch ステートメントにも適用されます。比較が === または !== の場合、値だけでなく型も比較するため、型変換は行われません。

トリックタイプのジャグリングをしたいなら

var_dump("10" == 0 + "10 ");  // true

それの訳は

PHP の自動型変換の例は、加算演算子 '+' です。いずれかのオペランドが float の場合、両方のオペランドが float として評価され、結果は float になります。それ以外の場合、オペランドは整数として解釈され、結果も整数になります。これはオペランド自体の型を変更しないことに注意してください。唯一の変更点は、オペランドの評価方法と、式自体の型です。

于 2012-10-13T11:55:12.310 に答える
1

確かな答えは compare_function 、php-src/Zend/zend_operators.c とそこで使用されているマクロの広大さのどこかに埋もれていると思います。

于 2012-10-13T12:19:08.087 に答える
0

この場合、最後の文字列を除くすべての「文字列」は、浮動小数点数または整数のように扱われ、比較されます。そのため、1 行目と 2 行目は true になります。

3 行目では、文字列にスペースが含まれています。これは、php にとっては「実際の」文字列であり、その行で文字列が比較されることを意味します。

私も言語は好きではありませんloose typedが、php の場合はこのように動作します。

于 2012-10-13T11:51:48.323 に答える