PHP の等価 (== 二重等しい) 比較演算子と同一性 (=== 三重等しい) 比較演算子はどのように異なりますか?

StackOverflow https://stackoverflow.com/questions/80646

質問

違いは何ですか == そして ===?

  • 緩くは具体的にどのように行われますか == 比較作業?
  • 厳密にはどのように正確に行われますか === 比較作業?

役に立つ例は何でしょうか?

役に立ちましたか?

解決

との差 == そして ===

ゆるりとの違い == 等価演算子と厳密な演算子 === 同一の演算子は正確に説明されています マニュアル:

比較演算子

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ Example  │ Name      │ Result                                                    │
├──────────┼───────────┼───────────────────────────────────────────────────────────┤
│$a ==  $b │ Equal     │ TRUE if $a is equal to $b after type juggling.            │
│$a === $b │ Identical │ TRUE if $a is equal to $b, and they are of the same type. │
└──────────┴───────────┴───────────────────────────────────────────────────────────┘

ゆるく == 同等の比較

を使用している場合は、 == 演算子、または次のような緩やかな比較を使用するその他の比較演算子 !=, <> または ==, 、常に見なければなりません。 コンテクスト 何が、どこで、そしてなぜ変換されるのかを確認して、何が起こっているかを理解するためです。

変換ルール

タイプ比較表

参考および例として、次の比較表を参照してください。 マニュアル:

との大まかな比較 ==

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ TRUE  │ FALSE │   1   │   0   │  -1   │  "1"  │  "0"  │ "-1"  │ NULL  │ array() │ "php" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ FALSE   │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ 1       │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 0       │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE   │ TRUE  │ TRUE  │
│ -1      │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "1"     │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "0"     │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "-1"    │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ NULL    │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ array() │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ FALSE │
│ "php"   │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ ""      │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE   │ FALSE │ TRUE  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

厳しい === 同一の比較

を使用している場合は、 === 演算子、または次のような厳密な比較を使用するその他の比較演算子 !== または ===, そうすると、型がそうでないことを常に確信できます。 魔法のように 変換が行われないため、変更されます。したがって、厳密な比較では、値だけでなく、型と値も同じである必要があります。

タイプ比較表

参考および例として、次の比較表を参照してください。 マニュアル:

との厳密な比較 ===

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ TRUE  │ FALSE │   1   │   0   │  -1   │  "1"  │  "0"  │ "-1"  │ NULL  │ array() │ "php" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ FALSE   │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 1       │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 0       │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ -1      │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "1"     │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "0"     │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "-1"    │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ NULL    │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE   │ FALSE │ FALSE │
│ array() │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE    │ FALSE │ FALSE │
│ "php"   │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ ""      │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ TRUE  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

他のヒント

演算子 == は 2 つの異なる型が異なる場合にキャストしますが、=== 演算子は「タイプセーフな比較」を実行します。つまり、両方のオペランドが同じ型と同じ値を持つ場合にのみ true を返します。

例:

1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value

警告:同等のメンバーを持つ同じクラスの 2 つのインスタンスは一致しません。 === オペレーター。例:

$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)

百聞は一見にしかず:

PHP の二重等しい == 等価グラフ:

enter image description here

PHP トリプルイコール === 平等グラフ:

enter image description here

これらのイメージを作成するソース コード:

https://github.com/sentientmachine/php_equality_charts

グル瞑想

正気を保ちたい人はこれ以上読まないでください。これは、PHP の狂気フラクタルがどのように設計されているかを言う以外には、何の意味もありません。

  1. NAN != NAN しかし NAN == true.
  2. == left が数値の場合、左右のオペランドを数値に変換します。それで 123 == "123foo", 、 しかし "123" != "123foo"
  3. 引用符で囲まれた 16 進文字列は浮動小数点になる場合があり、意図に反して不意に浮動小数点にキャストされ、実行時エラーが発生します。

  4. == は推移的ではないので、 "0"== 0, 、 そして 0 == "" しかし "0" != ""

  5. まだ宣言されていない PHP 変数は false です。PHP には未定義の変数を表す方法がありますが、その機能は次のコマンドで無効になります。 ==.
  6. "6" == " 6", "4.2" == "4.20", 、 そして "133" == "0133" しかし 133 != 0133. 。しかし "0x10" == "16" そして "1e3" == "1000" 予期せぬ文字列の 8 進数への変換を公開すると、ユーザーの指示や同意なしに実行され、実行時エラーが発生します。

  7. False == 0, "", [] そして "0".

  8. 数値が十分に大きい場合、それらは == 無限大になります。

  9. 新しいクラスは == から 1 です。

  10. False は他のほとんどの変数に対して == であり、ほとんどの場合その目的を果たさないため、False が最も危険な値です。

希望:

PHP を使用している場合は、二重等号演算子を使用しないでください。三重等号を使用する場合、心配する必要がある唯一のエッジ ケースは、NAN と無限に近すぎて無限にキャストされる数値だけだからです。二重のイコールがあれば、どんなことでも驚くことができる == 何かに、またはあなたの意志に反して不意に投げかけられる可能性があります。 != 明らかに等しいはずのものに。

どこで使っても == PHP には、何百万ものプログラマーがブラウン運動でプログラミングしていると思われる暗黙的なキャスト ルールによって 85 個のバグが暴露されているため、コードの臭いがひどいです。

JavaScript に関して:

=== 演算子は == 演算子と同じように機能しますが、オペランドの値が同じであるだけでなく、データ型も同じである必要があります。

たとえば、以下のサンプルでは、​​「x と y は等しい」と表示されますが、「x と y は同一です」は表示されません。

var x = 4;
var y = '4';
if (x == y) {
    alert('x and y are equal');
}
if (x === y) {
    alert('x and y are identical');
}

オブジェクト比較に関する他の回答への追加:

== は、オブジェクトの名前とその値を使用してオブジェクトを比較します。2 つのオブジェクトが同じ型で同じメンバー値を持つ場合、 $a == $b trueを返します。

=== オブジェクトの内部オブジェクト ID を比較します。たとえメンバーが同じだったとしても、 $a !== $b それらがまったく同じオブジェクトではない場合。

class TestClassA {
    public $a;
}

class TestClassB {
    public $a;
}

$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();

$a1->a = 10;
$a2->a = 10;
$b->a = 10;

$a1 == $a1;
$a1 == $a2;  // Same members
$a1 != $b;   // Different classes

$a1 === $a1;
$a1 !== $a2; // Not the same object

最も簡単に言うと:

== かどうかを確認します 同等 (値のみ)

=== かどうかを確認します。 同じ (値と型)


同等 vs.同じ:類推

1 + 1 = 2 + 0 (同等)

1 + 1 = 1 + 1 (同じ)


PHP の場合:

true == 1 (true - 値が同等)

true === 1 (false - 値と型が同じではありません)

  • 本当です ブール値
  • 1は 整数

すべてはデータ型に関するものです。取ってください BOOL (真または偽) 例:

true も等しい 1 そしてfalse も等しい 0

== 比較するときにデータ型を考慮しません。したがって、変数が 1 であるとします (これは、 true):

$var=1;

そして、それと比較してください ==:

if ($var == true)
{
    echo"var is true";
}

しかし $var 実際には等しくありません true, 、そうですか?int 値は次のとおりです。 1 代わりに、これは true と等しくなります。

===, 、データ型がチェックされ、2 つの変数/オブジェクト/その他が同じ型を使用しているかどうかが確認されます。

それで私がやったとしたら

if ($var === true)
{
    echo "var is true";
}

その条件は当てはまりません。 $var !== true それだけ == true (お分かりでしょうが)。

なぜこれが必要なのでしょうか?

簡単です - PHP の関数の 1 つを見てみましょう。 array_search():

array_search() この関数は単に配列内の値を検索し、値が見つかった要素のキーを返します。配列内で値が見つからなかった場合は、値が返されます。 間違い. 。しかし、もしあなたが array_search() に保存された値に基づいて、 配列の最初の要素 (配列キーは次のようになります) 0).... array_search() 関数は 0 を返します...これは false に等しいです。

したがって、次のようにした場合:

$arr = array("name");
if (array_search("name", $arr) == false)
{
    // This would return 0 (the key of the element the val was found
    // in), but because we're using ==, we'll think the function
    // actually returned false...when it didn't.
}

それで、これがどのように今問題になり得るかわかりますか?

ほとんどの人は使わない == false 関数が false を返すかどうかをチェックするとき。代わりに、彼らは !. 。しかし、実際には、これは使用するのとまったく同じです ==false, 、つまり、次のようにした場合:

$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)

そのような場合には、 === 代わりに、データ型がチェックされるようにします。

一例として、データベース属性は null または "" にすることができます。

$attributeFromArray = "";
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //true
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //false

$attributeFromArray = null;
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //false
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //true

与えられた x = 5

1) オペレーター:== は「等しい」です。 x == 8 偽です
2) オペレーター:=== は「完全に等しい」(値と型) x === 5 それは本当です、 x === "5" 偽です

いくつかの例

var_dump(5 == 5);    // True
var_dump(5 == "5");  // True because == checks only same value not type
var_dump(5 === 5);   // True
var_dump(5 === "5"); // False because value are same but data type are different.

追伸

== 値のみを比較します。データ型は気にしません

=== 値とデータ型を比較します

$a = 5;   // 5 as an integer

var_dump($a == 5);       // compare value; return true
var_dump($a == '5');     // compare value (ignore type); return true
var_dump($a === 5);      // compare type/value (integer vs. integer); return true
var_dump($a === '5');    // compare type/value (integer vs. string); return false

ただし注意してください。ここに悪名高い問題があります。

// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
    // code...
}

// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
    // code...
}

つまり、=== は、他のほとんどのプログラミング言語での == と同じように機能します。

PHP を使用すると、あまり意味のない比較を行うことができます。例:

$y = "wauv";
$x = false;
if ($x == $y)
    ...

これにより、いくつかの興味深い「ショートカット」が可能になりますが、返すべきではないもの (数値の代わりに「エラー」など) を返す関数は捕捉されず、何が起こったのか疑問に思うことになるため、注意する必要があります。

PHP では、== は値を比較し、必要に応じて型変換を実行します (たとえば、文字列「12343sdfjskfjds」は整数比較では「12343」になります)。=== は値と型を比較し、型が同じでない場合は false を返します。

PHP マニュアルを見ると、多くの関数は関数が失敗すると「false」を返すことがわかりますが、成功したシナリオでは 0 を返す可能性があるため、「if (function() !==」を実行することを推奨しています。 false)」を使用して間違いを避けてください。

=== を使用すると、単に false (ゼロまたは空の文字列) に等しいかどうかを関数または変数が false であるかどうかテストできます。

$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
    echo $needle . ' was not found in ' . $haystack;
} else {
    echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}

この場合、strpos は 0 を返し、テストでは false に相当します。

if ($pos == false)

または

if (!$pos)

それはあなたがここで望んでいることではありません。

一方を他方よりも使用する場合については、次の例を考えてみましょう。 fwrite() PHPの関数。

この関数は、コンテンツをファイル ストリームに書き込みます。PHPによると、「fwrite() 書き込まれたバイト数を返すか、エラーの場合は FALSE を返します。」関数呼び出しが成功したかどうかをテストしたい場合、このメソッドには欠陥があります。

if (!fwrite(stuff))
{
    log('error!');
}

ゼロを返しても (成功したとみなされます)、条件はトリガーされます。正しい方法は次のとおりです。

if (fwrite(stuff) === FALSE)
{
    log('error!');
}

PHP は、緩やかに型付けされた言語です。二重等号演算子を使用すると、変数を緩やかにチェックできます。

値を大まかにチェックすると、類似しているが等しくない値を同じものとして扱うことができます。

  • ''
  • ヌル
  • 間違い
  • 0

二重等号演算子を使用すると、これらの値はすべて等しいと見なされます。

php == は変数の値を比較する比較演算子です。ただし、=== は値とデータ型を比較します。

例えば、

<?php 
  $var1 = 10;
  $var2 = '10';

  if($var1 == $var2) {
    echo 'Variables are equal';
  } else {
    echo 'Variables are not equal';
  }
?>

この場合、データ型が異なっていても、出力は「変数は等しい」となります。

ただし、== の代わりに === を使用すると、出力は「変数が等しくない」になります。PHP は最初に変数の値を比較し、次にデータ型を比較します。ここでは値は同じですが、データ型が異なります。

変数には型と値があります。

  • $var = "test" は "test" を含む文字列です
  • $var2 = 24 は、値が 24 である整数です。

これらの変数を (PHP で) 使用する場合、適切な型がない場合があります。たとえば、次のようにすると

if ($var == 1) {... do something ...}

PHP は $var を整数に変換 (「キャスト」) する必要があります。この場合、空でない文字列は 1 にキャストされるため、「$var == 1」は true になります。

=== を使用する場合、値とタイプが等しいことを確認するため、「$var === 1」は false になります。

これは、たとえば、 false (エラーの場合) と 0 (結果) を返す関数がある場合に便利です。

if(myFunction() == false) { ... error on myFunction ... }

このコードはまるで間違っています myFunction() 0 を返すと false にキャストされ、エラーが発生しているようです。正しいコードは次のとおりです。

if(myFunction() === false) { ... error on myFunction ... }

なぜなら、テストは戻り値が「ブール値であり false である」ということであり、「false にキャストできる」ということではないからです。

=== 演算子は比較することになっています ちょうど コンテンツの平等性 == 演算子は意味上の同等性を比較します。特に、文字列を数値に強制変換します。

平等は広大なテーマです。見る 平等に関するウィキペディアの記事.

<?php

    /**
     * Comparison of two PHP objects                         ==     ===
     * Checks for
     * 1. References                                         yes    yes
     * 2. Instances with matching attributes and its values  yes    no
     * 3. Instances with different attributes                yes    no
     **/

    // There is no need to worry about comparing visibility of property or
    // method, because it will be the same whenever an object instance is
    // created, however visibility of an object can be modified during run
    // time using ReflectionClass()
    // http://php.net/manual/en/reflectionproperty.setaccessible.php
    //
    class Foo
    {
        public $foobar = 1;

        public function createNewProperty($name, $value)
        {
            $this->{$name} = $value;
        }
    }

    class Bar
    {
    }
    // 1. Object handles or references
    // Is an object a reference to itself or a clone or totally a different object?
    //
    //   ==  true   Name of two objects are same, for example, Foo() and Foo()
    //   ==  false  Name of two objects are different, for example, Foo() and Bar()
    //   === true   ID of two objects are same, for example, 1 and 1
    //   === false  ID of two objects are different, for example, 1 and 2

    echo "1. Object handles or references (both == and    ===) <br />";

    $bar = new Foo();    // New object Foo() created
    $bar2 = new Foo();   // New object Foo() created
    $baz = clone $bar;   // Object Foo() cloned
    $qux = $bar;         // Object Foo() referenced
    $norf = new Bar();   // New object Bar() created
    echo "bar";
    var_dump($bar);
    echo "baz";
    var_dump($baz);
    echo "qux";
    var_dump($qux);
    echo "bar2";
    var_dump($bar2);
    echo "norf";
    var_dump($norf);

    // Clone: == true and === false
    echo '$bar == $bar2';
    var_dump($bar == $bar2); // true

    echo '$bar === $bar2';
    var_dump($bar === $bar2); // false

    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    echo '$bar === $baz';
    var_dump($bar === $baz); // false

    // Object reference: == true and === true
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    echo '$bar === $qux';
    var_dump($bar === $qux); // true

    // Two different objects: == false and === false
    echo '$bar == $norf';
    var_dump($bar == $norf); // false

    echo '$bar === $norf';
    var_dump($bar === $norf); // false

    // 2. Instances with matching attributes and its values (only ==).
    //    What happens when objects (even in cloned object) have same
    //    attributes but varying values?

    // $foobar value is different
    echo "2. Instances with matching attributes  and its values (only ==) <br />";

    $baz->foobar = 2;
    echo '$foobar' . " value is different <br />";
    echo '$bar->foobar = ' . $bar->foobar . "<br />";
    echo '$baz->foobar = ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false

    // $foobar's value is the same again
    $baz->foobar = 1;
    echo '$foobar' . " value is the same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    // Changing values of properties in $qux object will change the property
    // value of $bar and evaluates true always, because $qux = &$bar.
    $qux->foobar = 2;
    echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
    echo '$qux->foobar is ' . $qux->foobar . "<br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    // 3. Instances with different attributes (only ==)
    //    What happens when objects have different attributes even though
    //    one of the attributes has same value?
    echo "3. Instances with different attributes (only ==) <br />";

    // Dynamically create a property with the name in $name and value
    // in $value for baz object
    $name = 'newproperty';
    $value = null;
    $baz->createNewProperty($name, $value);
    echo '$baz->newproperty is ' . $baz->{$name};
    var_dump($baz);

    $baz->foobar = 2;
    echo '$foobar' . " value is same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false
    var_dump($bar);
    var_dump($baz);
?>

これまでの回答はすべて、=== に関する危険な問題を無視しています。ついでに注意しましたが、強調しませんでしたが、integer と double は異なる型であるため、次のコードになります。

$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n ==  $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );

与える:

 equal
 not equal

これは「丸め誤差」の場合ではないことに注意してください。2 つの数値は最後のビットまでまったく同じですが、型が異なります。

=== を使用するプログラムは、すべての数値が十分に小さければ何年も問題なく実行できるため、これは厄介な問題です (「十分に小さい」とは、実行しているハードウェアと OS によって異なります)。ただし、偶然、整数が double に変換できるほど十分に大きい場合、後続の操作または多くの操作によって値が小さな整数に戻される可能性がある場合でも、その型は「永久に」変更されます。そして、状況はさらに悪化します。それは広がる可能性があります - 二重性感染は、一度に 1 回の計算で、触れるものすべてに伝染する可能性があります。

現実の世界では、これは、たとえば 2038 年以降の日付を処理するプログラムで問題になる可能性があります。現時点では、UNIX タイムスタンプ (1970-01-01 00:00:00 UTC からの秒数) は 32 ビットを超える必要があるため、一部のシステムではその表現が「魔法のように」 2 倍に切り替わります。したがって、2 つの時間の差を計算すると、2017 年に発生した整数の結果ではなく、2 倍の数秒になる可能性があります。

これは微妙なため、文字列と数値の間の変換よりもはるかに悪いと思います。何が文字列で何が数値であるかを追跡するのは簡単ですが、数値内のビット数を追跡​​するのは私には不可能です。

したがって、上記の回答にはいくつかの優れたテーブルがありますが、1(整数として)と1(微妙なdouble)および1.0(明らかなdouble)の区別はありません。また、常に === を使用し、決して == を使用しないようにするというアドバイスは、== が正常に機能する場合でも === が失敗することがあるため、あまり良くありません。また、JavaScript は数値型を 1 つしか持たないため、この点では同等ではありません (内部的には異なるビット単位の表現を持つ可能性がありますが、=== に関しては問題は発生しません)。

私のアドバイスは、どちらも使用しないことです。この混乱を実際に解決するには、独自の比較関数を作成する必要があります。

間には2つの違いがあります == そして === PHP の配列とオブジェクトについては、ここでは触れていないと思います。キーの種類が異なる 2 つの配列とオブジェクト。

異なるキーソートを持つ 2 つの配列

キー ソートを持つ配列と、異なるキー ソートを持つ別の配列がある場合、それらは厳密には異なります (すなわち、使用して ===)。これは、配列をキーソートし、ソートされた配列を元の配列と比較しようとした場合に発生する可能性があります。

たとえば、空の配列を考えてみましょう。まず、特別な並べ替えを行わずに、いくつかの新しいインデックスを配列にプッシュしようとします。良い例は、文字列をキーとして持つ配列です。ここで例を詳しく見てみましょう。

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

これで、ソートされていないキーの配列ができました (たとえば、「彼」は「あなた」の後に来ました)。同じ配列を考えますが、そのキーをアルファベット順にソートしました。

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

ヒント:次を使用して配列をキーでソートできます ksort() 関数。

これで、最初の配列とは異なるキーソートを持つ別の配列ができました。そこで、それらを比較してみます。

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

注記:当たり前かも知れませんが、二つを比べてみると 違う 厳密な比較を使用した配列は常に結果が得られます false. 。ただし、次を使用すると、2 つの任意の配列が等しい可能性があります。 === か否か。

あなたはこう言うでしょう:「この違いは無視できるほどです。」それから私は、それは違いであり、考慮されるべきであり、いつでも起こる可能性があると言います。上で述べたように、配列内のキーの並べ替えはその良い例です。

オブジェクト

覚えておいてください、 2 つの異なるオブジェクトが厳密に等しいことはありません. 。これらの例は次の場合に役立ちます。

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

注記:オブジェクトを別の変数に代入してもコピーは作成されません。むしろ、オブジェクトと同じメモリ位置への参照が作成されます。 ここを参照.

注記:PHP7以降では、 匿名クラス が追加されました。結果から言うと、両者に違いはありません new class {} そして new stdClass() 上記のテストでは。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top