prefabolic

123456789101112131415161718192021222324252627282930

まともなphperがいない

投稿者:kalibora
投稿日時:2006-07-31 - 01:34:52
カテゴリー:Programming - トラックバック(DISALLOWED (TrackBack))-
フラグなのに文字列を使ってたり、
定数なのにdefine使わなかったり、
あとみんな===演算子とか使わないのはなんで?
==だとちょっと怖くない?
だって
var_dump('0' == 0);
var_dump('' == 0);
var_dump(null == 0);
var_dump(false == 0);
var_dump('aaa' == 0);

これ全部 true だよ!
なんかいやじゃない?

ってまぁなんでこんなことを愚痴ったのかと言いますと、
仕事で使ってる某ライブラリでちょっとハマったのです。

あるクラス、例えばTheClassがありまして、
そのクラスに何がしかの内部状態を返すgetStatus()メソッドがあるとします。
$cls = new TheClass();
$status = $cls->getStatus();

こんな感じで。

そんでこのgetStatus()メソッドが返す値はライブラリの中で定義されてます。
define('STATUS1', 0);
define('STATUS2', 1);
define('STATUS3', 2);

こんな感じね。

で、その使い方のサンプルコードにはこんな風にかいてあります。
$cls = new TheClass();
$status = $cls->getStatus();
if ( $status == STAT1 ) {
  echo 'status1の時の処理';
}

うん、ここまでは問題ない。
そして自分は == よりも === の方が安全だなと思い、そのように書き換えました。
$cls = new TheClass();
$status = $cls->getStatus();
if ( $status === STAT1 ) {
  echo 'status1の時の処理';
}

そしたらですね。これが条件に通らないんですよ。
さっきまでは通っていたのに。

と、既にお気づきの方もおられると思いますが、
サンプルコードのif文の中の定数が間違っていたのですよ。

×if ( $status == STAT1 ) {
○if ( $status == STATUS1 ) {

STAT1 なんて定数はライブラリ中でどこにも定義されてなくて本当は STATUS1 なわけです。
でもサンプルコードでは STAT1 になっている。
単純にサンプルコードを書くときに書き間違えたんでしょうね。

でですね、これがエラーになればすぐ気づくので問題ないんですが、
この間違いなサンプルコードでも通っちゃうんです。
ためしに
var_dump( 0 == STAT1 );

とかやってみましょう。
trueになるはずです。
定義されていない定数STAT1は文字列"STAT1"とみなされ、それをintで評価すると0になるので結果的にSTATUS1と同等になってしまうというわけです。
でもこれ定義されていない定数を使った時点でNoticeレベルのエラーがでるはずです。
そう、だから本来はこれで気づくはずなんですが、

なんというかこのライブラリでは自前のエラーハンドラーを使ってまして、
そいつがE_WARNINGとE_NOTICEを捕捉してないんですね。
だからいくらWariningやNoticeを出そうが一切エラーログに吐かれない。

あーだから何が言いたいかといいますと
===使おうよと。見た目がゴージャスだし。

Comments

No comments yet

Add Comments

このアイテムは閉鎖されました。このアイテムへのコメントの追加、投票はできません。