My Photo

« Deferredで無限ループしてポーリング | Main | URLリライトの復習とIE11のUser-Agent »

April 14, 2014

PHPメモ038:PHPのswitchの比較は厳密な比較ではない

PHPの罠にはまった。
以下のような感じのコードを書いた。

switch ($type) {
case '01':
	$code = 'a';
	break;
case '02':
	$code = 'b';
	break;
default:
	$code = 'x';
}

$type が "01", "02", "99" の場合、$code は それぞれ "a", "b", "x" となった。想定通り。
しかし、$type が "1" の時に $code は "x" となると思っていたが、実際は "a" だった。
原因は、PHPのswitchの比較が厳密な比較(===)ではなく緩い比較(==)であるということだった。

以下のように書けば想定していた動作になるが、これなら else if で書いた方がいいなあ。

switch (TRUE){
case $type === '01':
	$code = 'a';
	break;
case $type === '02':
	$code = 'b';
	break;
default:
	$code = 'x';
}

今回の件で改めて、CとJavaで育った人間からするとPHPは不可解、直感的にわかりにくいと思った。switchのほかには3項演算子のこととか。
switch の件はリファレンスにちゃんと「緩い比較だよ」って書いてあるけど、既に他の言語をある程度使える人がわざわざswitchやら3項演算子の仕様を細かく確認しないでしょう。で、罠にはまって「あれ?」ってことになる。
言語仕様だけじゃなくて、ライブラリもなんだか名前や仕様が統一されていないように思う。isset() と is_int()など型を調べる関数で、なんでアンダースコアがあったりなかったりするのか。isset は関数じゃなくて言語構造だけど、でも似たようなジャンルのものでなぜこういう差異があるのかわからない。
他には配列操作関数の array_merge() と array_push()。array_merge() は結果が引数の配列への副作用として現れるが、array_push() は引数の配列には副作用がなく結果は返り値として現れる。この違いにちゃんとした理由があるのなら知りたい。

PHPはWebアプリを作る際には他の言語より少ない記述量で書ける点で便利ではあるが、言語としては一貫性というか統一感がなくて美しさに欠けるように思う。

参考ページ:
PHP: switch - Manual
れぶろぐ - [PHP] PHP の switch 文は怖くて使えない
PHP言語仕様のバグ - れぷそる・ふぁいやぁ・ぶれぇど

« Deferredで無限ループしてポーリング | Main | URLリライトの復習とIE11のUser-Agent »

PHP」カテゴリの記事

Comments

Post a comment

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/26461/59470841

Listed below are links to weblogs that reference PHPメモ038:PHPのswitchの比較は厳密な比較ではない:

« Deferredで無限ループしてポーリング | Main | URLリライトの復習とIE11のUser-Agent »

May 2017
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof