数値形式の文字列

PHP の 文字列 は、 intfloat と解釈できる場合は 数値と見なされます。

PHP 8.0.0 以降の正式な仕様は下記の通りです:

WHITESPACES      \s*
LNUM             [0-9]+
DNUM             ([0-9]*)[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM    (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
INT_NUM_STRING   {WHITESPACES} [+-]? {LNUM} {WHITESPACES}
FLOAT_NUM_STRING {WHITESPACES} [+-]? {EXPONENT_DNUM} {WHITESPACES}
NUM_STRING       ({INT_NUM_STRING} | {FLOAT_NUM_STRING})

PHP は 先頭から始まる 数値形式の文字列という概念も持っています。 これは、数値形式の文字列から始まり、その後に任意の文字が続く文字列です。

数値の文脈で使われる文字列

文字列が数値として評価される必要がある場合 (例: 算術演算や、int 型の宣言がある場合など) は、次のステップを踏むことで結果が決まります:

  1. 文字列が数値の場合、かつそれが int 型の範囲 (PHP_INT_MAX で定義されています) に含まれる場合、int に解決されます。 そうでない場合、float に解決されます。
  2. 文脈が 先頭から始まる数値形式の文字列を許す場合、 かつ値が文字列の場合は、次のように解決されます: 文字列の先頭部分が数値形式の文字列、かつそれが int 型の範囲 (PHP_INT_MAX で定義されています) に含まれる場合、int に解決されます。 そうでない場合、float に解決されます。 それに加えて、エラーレベル E_WARNING が発生します。
  3. 文字列が数値でない場合、 TypeError がスローされます。

PHP 8.0.0 より前の振る舞い

PHP 8.0.0 より前のバージョンでは、 先頭に ホワイトスペースがある場合にだけ、 文字列は数値と見なされていました。 数値の後に ホワイトスペースがある場合は、 その文字列は 先頭から始まる 数値形式の文字列とみなされていました。

PHP 8.0.0 より前のバージョンでは、 文字列が数値の文脈で使われる場合、既に述べたステップと同じ処理を行いますが、 以下の違いがあります:

  • 先頭から始まる数値形式の文字列の場合、 E_WARNING ではなく、 E_NOTICE が発生していました。
  • 文字列が数値でない場合、 E_WARNING が発生し、 0 が返されていました。
PHP 7.1.0 より前のバージョンでは、 E_NOTICEE_WARNING も発生していませんでした。

<?php
$foo 
"10.5";                // $foo は float (11.5)
$foo "-1.3e3";              // $foo は float (-1299)
$foo "bob-1.3e3";           // PHP 8.0.0 以降は TypeError。それより前は、$foo は integer (1)
$foo "bob3";                // PHP 8.0.0 以降は TypeError。それより前は、$foo は integer (1)
$foo "10 Small Pigs";       // PHP 8.0.0 では $foo は integer (11) で、かつ E_WARNING。それより前は E_NOTICE
$foo "10.2 Little Piggies"// PHP 8.0.0 では $foo は float (14.2) で、かつ E_WARNING。それより前は E_NOTICE
$foo "10.0 pigs " 1;          // PHP 8.0.0 では $foo は float (11) で、かつ E_WARNING。それより前は E_NOTICE
$foo "10.0 pigs " 1.0;        // PHP 8.0.0 では $foo は float (11) で、かつ E_WARNING。それより前は E_NOTICE
?>
関連キーワード:  数値, 形式, int, LNUM, 先頭, STRING, WHITESPACES, 解決, NUM, 発生