比較演算子===と!==について

このQ&Aのポイント
  • PHP初心者のため、比較演算子===と!==について質問があります。
  • ===と!==は、型まで比較する演算子です。
  • 例えば、同じ値でも型が違う場合、===ではfalseになることがあります。
回答を見る
  • ベストアンサー

比較演算子===と!==について

PHP初心者です。 まず、===と!==が型が同じかどうかを比較する演算子だという事は調べて分かりました。 問題は以下のソースコードに関してです。 <?php class foo { public $a = 3; } class hoge { public $a = 3; } //真偽を文字列に変換する関数 function trueOrFalse($comp) { return $comp? 'true':'false'; } //4つの比較演算子を用いた比較の結果の表示 function compareObject($var1, $var2) { print('$var1 == $var2 --'.trueOrFalse($var1 == $var2)."\n"); print('$var1 != $var2 --'.trueOrFalse($var1 != $var2)."\n"); print('$var1 === $var2 --'.trueOrFalse($var1 === $var2)."\n"); print('$var1 !== $var2 --'.trueOrFalse($var1 !== $var2)."\n"); } //オブジェクトの生成 $f0 = new foo(); $f1 = new foo(); //$f0を代入、$f2は、$f0と同じオブジェクトを指す $f2 = $f0; $h0 = new hoge(); //結果の表示 print("同じクラス、プロパティが同じ\n"); compareObject($f0, $f1); print("同じオブジェクトを参照\n"); compareObject($f0, $f2); print("異なるクラス、プロパティは同じ\n"); compareObject($f0, $h0); ?> この結果分からないのは$f0と$f1の比較で===はfalseに!==はtrueになる事です。 型が違うとは一体どういう事なのでしょうか。 また、付け足す形になりますが、$f0と$h0の比較についても分かりません。 値は両方3です。 なのに==はfalseに!=はtrueになります。 これはどうしてでしょうか。 アドバイスどうぞ宜しくお願い致します。

  • PHP
  • 回答数5
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.4

$f0 = new foo(); $f1 = new foo(); 共に同じfooクラスのインスタンスです。 が、別別のインスタンスです。 「一致演算子(===)を使用する場合、 オブジェクト変数は、同じクラスの同じインスタンスを参照する場合のみ、 等しいとされます。 」 とあります。 一方 「比較演算子(==)を使用する際、 オブジェクト変数は、単純に比較されます。つまり、 二つのオブジェクトのインスタンスは、 同じ属性と値を有し、同じクラスのインスタンスである場合に、 等しいとされます。 」 とあります。 $f0と$h0は別のクラスです。よって $f0==$h0は偽です。

persona
質問者

お礼

親切丁寧な回答に感謝します。 これで両方とも疑問が解決できました。

その他の回答 (4)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.5

PHPの設計者が 一致演算子(===)を使用する場合、オブジェクト変数は、同じクラスの同じインスタンスを参照する場合のみ、等しいとされます。 と決めたのでそういうものと理解するしかないですね

persona
質問者

お礼

アドバイスありがとうございます。 なるほど、数学の公式のような感じですかね。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

==は一致で、===は完全一致ですね。 ==ではあいまいに一致を判断するので厳密にはんだするためには ===を使います <? $a=null; if($a=="" && is_null($a) && empty($a) && $a==0) print 1; ?> これで1が表示されます。 つまり型が違うと、nullと空(empty)と""と0とfalseは同じなんです。 厳密にチェックするにはこうなりますね・・・・ <? $a=null; if($a=="" && $a==0 && $a==false && is_null($a) && empty($a)) print 1; if($a==="") print 2; if($a===0) print 3; if($a===false) print 4; if($a===null) print 5; ?>

persona
質問者

お礼

アドバイスありがとうございます。 回答頂いた内容については理解できたつもりです。 その上で言葉足らずの部分を補い、もう1度質問しても宜しいでしょうか。 $f0 = new foo(); $f1 = new foo(); 共に同じfooクラスのインスタンスです。 これが完全一致しないのは何故でしょうか。 もう1つここは同じ文になりますが、$f0と$h0の比較についても分かりません。 両方の値は3です。 なのに==はfalseに!=はtrueになります。 何故値は同じなのに一致しないのでしょうか。 この2点について再度アドバイスを頂けると非常に助かります。 答えるかどうかはyambejpさんに全てお任せします。 どうぞ宜しくお願い致します。

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.2

No.1回答者です。失礼しました、マニュアルの(例)とほとんど同じ物を質問されているのですね。つまりマニュアルの意味がわからないということですね。

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.1

オブジェクトの比較については、マニュアルで説明されています。 http://www.php.net/manual/ja/language.oop5.object-comparison.php

関連するQ&A

  • Java のinstanceof 演算子について

    Sun Java2 認定ガイドの168 ページに次のコードを前提とした場合のinstanceof テスト結果が示されている。 このようなテスト結果が得られるプログラムのコーディングを教えてください。 *前提とするコード interface Face { } class Bar implements Face { } class Foo extends Bar { } *instanceof 演算子のオペランドとテスト結果(表) 1番目のオペランド  instanceof オペランド      テスト結果 null        すべてのclass型又はinterface型    false Fooインスタンス   Foo、Bar、Face、Object        true Barインスタンス   Bar、Face、Object           true Barインスタンス   Foo                  false Foo[]        Foo、Bar、Face            false Foo[]        Object                true Foo[1]        Foo、Bar、Face、Object        true 以上です。例えば、2行目のFooインスタンスとBarの比較は次のようにやればよいと思いますが、Foo[]やFoo[1]についてはどうコーディングすればよいのでしょうか? Foo f = new Foo(); boolean b = f instanceof Bar; // bをプリントする     

  • PHPの文字列の比較について

    PHPの文字列の比較について質問です。 $hoge = "文字列¥¥テスト"; $foo = "文字列¥テスト"; とあった場合 var_dump($hoge == $foo); とすると trueがかえってきます。 バイト列としてみた場合 エスケープしたバックスラッシュと 構文上、エスケープの必要のないバックスラッシュの文字列上の 比較ですがこれが、なぜかtrueがかえってきます。 これは、当然の結果なのでしょうか? PHPは文字列を比較するさい、バイト列としての文字列のならびより アウトプットされる結果を比較しているということでしょうか? それとも、単純に上記変数$hogeと$fooはバスックスラッシュの使用方法は 関係なく同一のものとして扱われるのでしょうか?

    • 締切済み
    • PHP
  • JavaScriptでインスタンスを比較してみたい

    JavaScriptでインスタンスを比較してみたいのですが、色々分からないことがあるので教えてください。 ■質問1 ・そもそも、JavaScriptにインスタンスはあるのでしょうか? ■質問2 ・下記で「hoge1」「hoge2」はインスタンスではないのでしょうか?(単にオブジェクトを取得しているだけ?) var myApp = {  point: 0,  setPoint: function(p){   this.point= p;  },  getPoint: function(){   return this.point;  } }; myApp.point = 5; var hoge1 = myApp.getPoint(); var hoge2 = myApp.getPoint(); console.log( hoge1 === hoge2 ); // true ■質問3 ・「Object.create」か「new」すれば、インスタンス生成できる? ■質問4 ・インスタンスの比較はどうやるのでしょうか? ・「===」?

  • 演算子is... 初学者 Python 3

    毎度おせわさまです。Pythonに関する質問です。 今回は演算子isについて。 ネット上の初心者むけサイトで独学に励んでいるのですが、演算子isは、左辺と右辺のオブジェクトが同じオブジェクトだった場合には「True」を返します、とありました。 変数を、 str1 = "555" str2 = "555" として、 print str1 == str21 #1 print str1 is str2 #2 とすると #1は、オブジェクトの値が同じなのでTrueを返すが、#2はオブジェクトが同一ではないのでFalseを返す、と。 なるほど、なるほど。と思いながら実際に書いてみると、#1も#2もTrueを返すのですが・・・・・ バージョンの違いでしょうか?なんでしょうか???今使ているのはPython2.7です。 ご回答よろしくお願いいたします。

  • アロー演算子について

    php素人です アロー演算子についてわかりやすく教えてください クラスとか使ったことありませんのでアロー演算子をみるとパソコンの前から逃げ出したくなります 質問1 アロー演算子を使うときはクラス内の変数などにアクセスするときだけですか?(普通はclassを使わない場合、アロー演算子は使わないのですか?) 質問2 他のファイルから呼び出す場合はrequire_onceなどをつかってからアロー演算子でよびだすのですか? 質問3 PDOもrequire_onceなどで呼び出してからつかってるのですか? 質問4 下記のようにclassを定義する前にnewでオブジェクトを出現させても大丈夫なんですか? 質問5 アロー演算子とはクラスから変数や関数を使うためのものですか?下記の場合、 $hoge変数にclass numberdayoの処理が詰まっているってことでしょうか? $hoge = new numberdayo(); $hoge ->number = 2; $hoge ->numberdayo(); class numberdayo{ public $number; function numberdayo(){ print($this -> number); } } 質問6 別の質問ですが、classをつかってない単なる関数functionは定義する前に呼び出せますか? hoge(); function hoge(){ print("関数"); } よろしくお願いします

    • ベストアンサー
    • PHP
  • XAMPを使っているのですが、論理演算子がうまく機能しません。

    XAMPを使って、PHPプログラムの練習をしています。 論理演算子を試しているですが、本に書いてあるような結果に なりません。phpバージョンはPHP 5.3.0です。 $f = true; $g = false; $h = $f and $g; $i = $g and $f; echo "result:".$h; $hも$gも同じように結果は空白になるはずなのですが、$hのほうは 1が返ってきます。なにが原因なのでしょうか?よろしくお願いします。

    • ベストアンサー
    • PHP
  • javascript new演算子について質問があります。

    javascript new演算子について質問があります。 只今javascript勉強中なのですが、どこかのサイトでnew演算子は悪いパーツとの 記事を読みました。 そこでnew演算子を使用せずにオブジェクト生成の方法を試行錯誤考えてみたのですが (IE用に__proto__もなしで)例えば以下コードはアリなコードでしょうか?? あるいはありえない感じでしょうか?? またnewが悪なのはインスタンスを作る時にnewを付け忘れると、 グローバルな汚染をしてしまうということだけなのでしょうか?? オブジェクトとプロトタイプの理解に苦しんでいるところなので 色々と曖昧なのですが、どなたかどうぞご教授お願い致します。 var obj = {}; obj.method = function(){ this.prop1 = "hoge" return this; }; obj.method.prototype = obj.method(); obj.method.prototype.prop2 = "fuga"; var obj2 = obj.method(); console.log(obj2)

  • 演算結果はカタカナだとどう呼びますか?

    オペランド(operand)は被演算数です。 オペレータ(operator)は演算子です。 では、 ______________________________は演算結果です。 ↑ここに入るのは何がしっくりくるでしょうか? 例 2+3=5のとき 2と3がオペランドです。 +がオペレータです。 5は対応する呼び方があるとすると、なんと呼ぶとよいでしょうか。 =には、触れないでおきます。 ()のある計算式で、括弧中を塊としてみたときに、 式つまり、オペランドとオペレータの列に見えたり、 一つの演算結果に見えたりして、困ります。 例¬(true || false) が¬trueだったり、falseだったりします。 さいごの3つ目のfalseはオペランドでも、オペレータでもなく、演算結果だと思います。 キャルキュレーションみたいな名前があるのでしょうか?

  • Array#eachのブロック中で要素追加

    初歩的な質問で申し訳ありません ary = [Foo.new] ary.each do |i|  if (条件)   ary.push(Foo.new)  end end 上の様にブロックの中である条件でaryに要素が追加されます。 この場合、この追加された要素はeachで漏れなく扱えるのでしょうか? 簡単なプログラムで試した限りではpushされたFooインスタンスについてもeachで取り出せているようなのですが、自信が無いので質問致します。 # coding: windows-31J class Foo attr_accessor :checked attr_reader :val RAND_MAX = 5 def initialize rnd = Random.new @checked = false @val = rnd.rand(RAND_MAX).to_i end end ary = [Foo.new] ary.each do |f| if f.val > 0 ary.push(Foo.new) end f.checked = true end cnt_true = 0 cnt_false = 0 ary.each_index do |idx| print "#{idx} #{ary[idx].checked} #{ary[idx].val}\n" if ary[idx].checked cnt_true += 1 else cnt_false += 1 end end puts "checked true = #{cnt_true}" puts "checked false = #{cnt_false}" よろしくお願いします。

    • ベストアンサー
    • Ruby
  • javascriptを只今勉強中なのですが、オブジェクトについてこんが

    javascriptを只今勉強中なのですが、オブジェクトについてこんがらがってしまいました。 var obj = new Object(); var obj2 = {}; Object.prototype.prop1 = "hoge"; obj,obj2共にprop1にhogeがセットされるのですが、オブジェクトリテラルのobj2は Objectコンストラクタのインスタンスと解釈できるのでしょうか?? new演算子について色々とfirebugで調べていたところこの疑問が出てきました。 newなしでもインスタンスができるのでしょうか? オブジェクトを理解していないので意味不明な質問かもしれませんが どなたかアドバイスいただけると嬉しいです。

専門家に質問してみよう