適切な数の型にキャストって

数値がらみの話で hnw さんにすこしでも絡めるべく。

どうしてもis_numeric()が使いたいのであれば、is_numeric()がtrueを返した直後に整数なり浮動小数点数なりにキャストすれば問題が起こることは無いはずです。

http://openlab.dino.co.jp/2007/11/23/121351149.html

型にゆるい php なんだからとりあえず floatval() でもすればいいっちゃいいんですが、 int な文字列だったらちゃんと int にしたいときは、"+ 0" してあげるとうまいことキャストされてくれます。

$n $n + 0 is_numeric ctype_digit
string(1) "0" int(0) true true
string(1) "1" int(1) true true
string(2) "-1" int(-1) true false
string(3) "0.0" float(0) true false
string(3) "1.0" float(1) true false
string(3) "1.1" float(1.1) true false
string(4) "-1.1" float(-1.1) true false
string(6) "1.3e+3" float(1300) true false
string(7) "-1.3e-3" float(-0.0013) true false
string(4) "0xab" int(171) true false
string(3) "aho" int(0) false false

ちなみに、たんに $n ~ /^[0-9]+$/ を調べたいときは ctype_digit のほうがほんのちょっとだけ速いみたいですね。

何してるのかな?

と、"+ 0" は経験則だったんだけど、実は判定方法に違いがあるとかだったら悲しいのでちょっと調べてみた。

is_numeric() は ext/standard/type.c の中で PHP_FUNCTION として定義されてますが、実体は Zend/zend_operator.h にある inline 関数の is_numeric_string() を呼んでいるだけ。で、これは '+' の実装である add_function() の中で呼ばれる convert_scalar_to_number() のさらに中で使ってるやつです。

なので、いわば「is_numeric()でtrueなのは分かったけど、具体的に int だったの? float だったの?」てのがちゃんと使えてるってことのようです。ちょっと安心。