2011年5月17日火曜日

PHPでオブジェクトと文字列を比較する

PHPを使っていて、ずーっと腑に落ちないことがあったけど、今さっきすっきりしたのでメモっておくことにする。

まず、ここにXMLを読み込んでオブジェクト化するコードがある。

XMLをオブジェクト化

// XMLデータを適当に定義
$plain_xml = '<hoge><foo>bar</foo></hoge>';

// 解析してSimpleXMLElementオブジェクトにする
$xml_obj = simplexml_load_string($plain_xml);

// fooタグの型を調べてみる
//   SimpleXMLElementと出力される
echo get_class($xml_obj->foo);

今回は、<hoge>というルートタグに囲まれた<foo>タグに文字列barが格納されたXMLを用意した。これをオブジェクト化したものも、子要素の<foo>タグをオブジェクト化したものも、共にSimpleXMLElement型であることが確認できる。

この後が不思議。

不思議なコード

if ("bar" == $xml_obj->foo)
 echo "TRUE";
else
 echo "FALSE";

みたまんま。TRUEと出力される。直感的にはよく分かるし何も問題無い気がする。が、前項にあった通り$xml_obj->fooは、SimpleXMLElement型であり"bar"は見た通り文字列型である。つまり「===」で比較すればFALSEとなる関係にある。なぜすんなりと比較できているのか不思議ぃ。

ところでJavaの場合、上記の例は必ずFALSEになる。Javaでの「==」による比較は、ポインタが指し示すアドレスの比較であり「"bar"」と「$xml_obj->foo」が同じ位置を指し示すことはない。Javaに慣れ親しんでいると、「"文字列"」と「==」が隣同士に並ぶことはありえないといった感覚をもつ人が多いと思う。

そんなJavaな感覚に基づいた違和感と、PHPの基礎すら勉強していないという怠惰な自分のせいで不思議な感じがしていたけど、実はPHPにも__toString()というマジックメソッドが用意されている。以下マニュアルより引用。

__toString

__toString メソッドにより、 クラスが文字列に変換される際の動作を決めることができます。たとえば echo $obj; としたときに何を表示させるかといったことです。

また忘れた時のために、まとめておくと

0 件のコメント:

コメントを投稿