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


509

違いは何である==とは===

  • 大まかな==比較はどの程度正確に機能しますか?
  • 厳密な===比較はどの程度正確に機能しますか?

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

回答:


633

=====

緩やかに==等しい演算子と厳密に===同一の演算子の違いは、マニュアルで正確に説明されています

比較演算子

┌──────────┬───────────┬─────────────────────────── ─────────────────────────────────┐
│例│名前│結果│
├──────────┼───────────┼─────────────────────────── ─────────────────────────────────┤
│$ a == $ b│等しい│タイプジャグリング後の$ aが$ bと等しい場合はTRUE。│
│$ a === $ b│同一│$ aが$ bと等しく、同じタイプの場合はTRUE。│
└──────────┴───────────┴─────────────────────────── ─────────────────────────────────┘

大まかに==等しい比較

使用している場合は==、オペレータ、または緩く比較を使用する他の比較演算子をのような!=<>または==、あなたは常に見ている文脈に何かが起こっているかを理解するために変換されますなぜ、何を、見て。

ルールの変換

型比較表

参照と例として、マニュアルの比較表を見ることができます

との緩い比較 ==

┌─────────┬───────┬───────┬───────┬───────┬──────── ┬───────┬───────┬───────┬───────┬─────────┬──────── ┬───────┐
││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│真│偽│真│偽│偽│真│偽│偽│偽│偽│偽│偽│
│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」│真│偽│真│偽│偽│真│偽│偽│偽│偽│偽│偽│
│「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」│「」│
├─────────┼───────┼───────┼───────┼───────┼──────── ┼───────┼───────┼───────┼───────┼─────────┼──────── ┼───────┤
│真│真│偽│偽│偽│偽│偽│偽│偽│偽│偽│偽│偽│
│偽│偽│真│偽│偽│偽│偽│偽│偽│偽│偽│偽│偽││
│1│偽│偽│真│偽│偽│偽│偽│偽│偽│偽│偽│偽│
│0│偽│偽│偽│真│偽│偽│偽│偽│偽│偽│偽│偽│
│-1│偽│偽│偽│偽│真│偽│偽│偽│偽│偽│偽│偽│
│「1」│偽│偽│偽│偽│偽│真│偽│偽│偽│偽│偽│偽│
│「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│FALSE│TRUE│
└─────────┴───────┴───────┴───────┴───────┴──────── ┴───────┴───────┴───────┴───────┴─────────┴──────── ┴───────┘

66
他の誰かが「000」==「0000」というのは奇妙だと思いますか?
nickf 2008

36
いつも私を驚かせているのは、false == array()、false == 0ですが、array()!= 0なので、false == array()!= / == 0?それは私には奇妙に感じます。
Pim Jager

4
@Pim ...続き:このように見てください:BOOLにキャストする場合、どの値も2つの側のtrueいずれかにある必要がありfalseます。キャストは簡単です。ただし、他のすべての値には、実用上、実質的に無制限の組み合わせがあります。ですか"five" == 5array(0) == 0array(0,0,0) == 00.0000000000000000000000000000000000000000000000000001 == array()
だます

12
@Raithlin、配列に注意。triple equalsはfalse、JavaScriptのさまざまな配列を提供しますがtrue、PHPの場合は、それらの値が等しい場合に限ります。
Pacerier 2013

14
@Raithlin、さらに多くの落とし穴。JavaScriptで: "000" != "00""000" == null"000" == false"0x0" == falsearray() == 0false != nullarray() != nullfalse == "0x0"false == "000"PHPには、反対の行動です: "000" == "00""000" != null"000" != false"0x0" != falsearray() != 0false == nullarray() == nullfalse != "0x0"false != "000"
Pacerier 2013

239

演算子==は、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)

3
Nitpick:===は、両方のオペランドが同じタイプで値が等しい場合にのみtrueを返します=)
gnud

1
@gnudそれはまさに彼が例で示したものです。タイプを比較するだけの場合は、単に「タイプ比較」と呼ばれます。
Rob Stevenson-Leggett

3
8年間のPHPを使用した後、昨日は私が===使用したはずな状況に巻き込まれた初めてだった

3
===それらが等しく、同じタイプである場合はtrue。==それらが等しい場合はtrue。!=等しくない場合はtrue。!==等しくないか、等しいが同じ型ではない場合はtrue。
ジェレミーC

1
また、===を使用すると、==よりもわずかに高速です。これは、値が等しいかどうかを確認する前に値を変換する必要がないためです。
クロージエール2014年

88

写真は千の言葉に値します:

PHP Double Equals ==等価チャート:

ここに画像の説明を入力してください

PHP Triple Equals ===Equalityチャート:

ここに画像の説明を入力してください

これらの画像を作成するためのソースコード:

https://github.com/sentientmachine/php_equality_charts

達人瞑想

PHPの狂気のフラクタルがこのように設計されたと言うことを除いて、これはどれも意味がないので、正気を保ちたい人はこれ以上読みません。

  1. NAN != NANしかしNAN == true
  2. ==左が数値の場合、左と右のオペランドを数値に変換します。なので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と無限に近い数値のみであり、無限にキャストされるためです。二重のイコールを使用すると、何かは何かに驚い==たり、意志に逆らったり、!=明らかに等しいはずの何かに驚いたりすることができます。

==ブラウン運動でプログラミングする何百万人ものプログラマーによって設計されたように見える暗黙のキャストルールによって露呈される85のバグのため、PHPで使用する場所はどこでも悪いコード臭です。


常に三重の等号を使用することは本当に良い考えですか(これも安全です)?
Chazy Chaz 2017年

3
はい、トリプルイコールの推移的なプロパティにより、より安全でWebスケールになります。
Eric Leschinski、2017年

数値を無限に近づけるにはどうすればよいですか?[爆発する脳のgif]
ティム

40

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');
}

これはphpの場合とまったく同じように思われるため、賛成です。
デビッドはモニカを

1
それはsame.See正確ではありません@DavidThomas stackoverflow.com/questions/12598407/...
xdazz

22

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

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

===オブジェクトの内部オブジェクト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

12

最も簡単な言葉で:

== 同等かどうかをチェックします(値のみ)

=== 同じ(値&&タイプ)


同等同じかをチェック:類推

1 + 1 = 2 + 0(同等)

1 + 1 = 1 + 1(同じ)


PHPの場合:

true == 1true-値は同等)

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

  • 真はブールです
  • 1はint

「===が同じかどうかを確認します(値&&タイプ)」、正確には当てはまりません 2つのstdClassオブジェクトは同じタイプの「オブジェクト」(つまり、gettype()を使用)を持っていますが、PHPは、厳密な比較を使用する場合、2つの異なるものであると言います。こちらをご覧ください
MAChitgarha

8

それはすべてデータ型に関するものです。BOOL(trueまたはfalse)を例にとります:

trueまた等しい1falseまた等しい0

==比較するデータの種類を気にしません:あなたは(もすることができた1である変数を持っていたので、あればtrue):

$var=1;

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

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

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

では===、データ型を作るためにチェックされていることを確認二つの変数/オブジェクト/同じタイプを使用しているものは何でも。

だから私がしたなら

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

その条件は(それが私が何を意味するかを知っている場合$var !== trueに限り)真実ではありません== true

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

シンプル-PHPの機能の1つを見てみましょうarray_search()

このarray_search()関数は、単に配列内の値を検索し、値が見つかった要素のキーを返します。値が配列内に見つからなかった場合は、falseを返します。しかし、配列の最初の要素(配列キーが)array_search()に格納されている値に対してを実行した場合はどうなりますか。関数は0を返します。0array_search()

だからあなたがしたなら:

$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)

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


8

1つの例は、データベース属性が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

7

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

例えば、

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

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

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

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


6

与えられた x = 5

1)演算子:==は「等しい」です。x == 8is false
2)演算子:===は「完全に等しい」(値と型)x === 5はtrue、x === "5"false


3
$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...
}

3

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

PHPでは、実際には意味のない比較を行うことができます。例:

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

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

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

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


1
これらの「ショートカット」に加えて、==演算子の異常な振る舞いがセキュリティホールを開くことがわかっていることに注意してください。 if(databasehash == cookiehash)検証。
デビッド

3

いくつかの例

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.

PS

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

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


この答えの問題は何ですか?
Mohit Tanwani

2

===を使用して、関数または変数が単なる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)

これはあなたがここで望むものではありません。


2

どちらを使用するかについてはfwrite()、PHP の関数を例にとります。

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

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

ゼロを返すことができ(成功と見なされます)、条件は引き続きトリガーされます。正しい方法は次のとおりです。

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

2

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

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

  • ヌル
  • 0

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


1

変数にはタイプと値があります。

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

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

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

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

===を使用する場合、値AND THE TYPEが等しいことを確認するため、「$ var === 1」はfalseです。

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

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

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

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

テストは、戻り値が「ブール値であり、偽である」ことをテストするものであり、「偽にキャストすることはできない」ためです。


空でない文字列に関しては、実際にはそうではありません。"a" == 0はTRUEです。
nickf 2008

1

===オペレータは、比較することが想定され、正確な一方で、コンテンツの平等を==オペレータがセマンティック平等を比較します。特に、文字列を数値に強制変換します。

平等は広大な主題です。平等に関するウィキペディアの記事を参照してください。


1
<?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);
?>

1

これまでのすべての回答は、===の危険な問題を無視しています。ちなみに、強調されていませんが、整数と倍精度浮動小数点数は異なる型であるため、次のコードを使用します。

$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つの時間の差を計算すると、2017年に発生する整数の結果ではなく、数秒で結果が2倍になる可能性があります。

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

したがって、上記の回答にはいくつかの素晴らしいテーブルがありますが、1(整数として)と1(微妙なdouble)と1.0(明白なdouble)の違いはありません。また、==が適切に機能する場合に===が失敗することがあるので、常に===を使用し、決して==を使用しないようにというアドバイスは適切ではありません。また、JavaScriptは数値タイプが1つしかないため、この点では同等ではありません(内部的にはビットごとの表現が異なる場合がありますが、===で問題が発生することはありません)。

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


0

PHPの配列とオブジェクトの間には=====ここで言及しなかった2つの違いがあります。キーの並べ替えが異なる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

:明白な場合もありますが、厳密な比較を使用して2つの異なる配列を比較すると、常に結果が得られ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()上記のテストでは。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.