LoginSignup
6
4

More than 5 years have passed since last update.

is_numeric関数の挙動がドキュメントに従っていない

Posted at

is_numeric関数は、数値形式の文字列かどうかを判定する関数です。
その基準について、ドキュメントには以下のように記載されています。

PHP: is_numeric - Manual

指定した変数が数値であるかどうかを調べます。数値形式の文字列は以下の要素から なります。(オプションの)符号、任意の数の数字、(オプションの)小数部、 そして(オプションの)指数部。つまり、+0123.45e6 は数値として有効な値です。十六進表記(0xf4c3b00c など) や二進表記 (0b10100111001 など)、そして八進表記 (0777 など) は認められません。

バージョン 説明
7.0.0 十六進表記(0xf4c3b00c など) の文字列は数値形式の文字列とみなされなくなりました。 つまり、is_numeric()FALSE を返すようになりました。

これに従うならば、以下のコードは

<?php

/**
 * 出力をテキストとして表示するため、テキストファイルのContent-Typeを送信
 */
header('Content-Type: text/plain');

$tests = [
    '42', // 普通の数値
    '0xf4c3b00c', // 十六進表記
    '0777', // 八進表記
    '0b10100111001', // 二進表記
    '1337e0', // 指数部を含む数値
    '+42', // 符号付きの数値
    '3.141592', // 小数部を含む数値
    'not numeric', // 数値ではない文字列
];

foreach ($tests as $element) {
    echo '"', $element, '" is' . (is_numeric($element) ? '' : ' NOT') . ' numeric', PHP_EOL;
}

このような出力となるはずです。

PHP 7以上
"42" is numeric
"0xf4c3b00c" is NOT numeric
"0777" is NOT numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

PHP 7未満
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is NOT numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

しかし、実際に実行してみると…

PHP 7.0.0beta2の場合

PHP 7.0.0beta2
"42" is numeric
"0xf4c3b00c" is NOT numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is NOT numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 7.0.0alpha2の場合

PHP 7.0.0alpha2
"42" is numeric
"0xf4c3b00c" is NOT numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is NOT numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 5.6.8の場合

PHP 5.6.8
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 5.6.10の場合

PHP 5.6.10
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 5.5.24の場合

PHP 5.5.24
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 5.4.42の場合

PHP 5.4.42
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

PHP 5.4.40の場合

PHP 5.4.40
"42" is numeric
"0xf4c3b00c" is numeric
"0777" is numeric
"0b10100111001" is NOT numeric
"1337e0" is numeric
"+42" is numeric
"3.141592" is numeric
"not numeric" is NOT numeric

ドキュメントに従った動作との差分
 "42" is numeric
 "0xf4c3b00c" is numeric
-"0777" is NOT numeric
+"0777" is numeric
 "0b10100111001" is NOT numeric
 "1337e0" is numeric
 "+42" is numeric
 "3.141592" is numeric
 "not numeric" is NOT numeric

ドキュメントでは、八進表記(0777など)は認められないと明記されています。
にも関わらず、すべてのバージョンのPHPにおいて、明らかに八進表記でtrueが返されています。

6
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4