Signature
is_numeric(mixed $value): boolPurpose
is_numeric() answers one question: can this value be treated as a number without losing information? It returns true for integers, floats and strings that follow PHP's numeric string format. Everything else gives false. It is typically used on loosely typed input, such as form fields or parsed text, before the value goes into arithmetic or a comparison.
The function checks the shape of a value. It does not convert the value, and it does not tell you whether the result is an int or a float.
Signature
Parameters and defaults
$value: any value. There are no other parameters and no defaults. You can pass strings, numbers,null, booleans, arrays or objects without causing a type error.
Return value and failure cases
The function returns a bool. It never throws for ordinary input and never emits a warning. Unsuitable input simply returns false. That includes:
null, booleans and arrays- the empty string
- strings with trailing junk, such as
"42abc" - strings in hexadecimal or binary notation, such as
"0x1A"
Integer and float values always count as numeric. A string counts when it is an optional sign, digits with an optional decimal point, and an optional exponent, possibly surrounded by whitespace. Strings such as "-3.14", "1e3" and ".5" qualify.
Example 1: Checking a mix of types
This example shows numeric strings, real numbers and several values that fail.
$values = ["42", "-3.14", "1e3", ".5", 10, 2.5, "0x1A", "abc", "", null, true];
$result = [];
foreach ($values as $value) {
$result[] = is_numeric($value);
}
echo json_encode($result), PHP_EOL;[true,true,true,true,true,true,false,false,false,false,false]
The first six entries are numeric. The hexadecimal string, the word, the empty string, null and true are not.
Example 2: Whitespace rules
Leading whitespace has long been allowed. Since PHP 8.0, trailing whitespace is allowed too, so "42 " returns true. Before 8.0 it returned false. Whitespace in the middle of a string is never allowed, and a non-breaking space is not treated as whitespace here.
$inputs = [" 42", "42 ", "42abc", "4 2", "\u{A0}9001"];
$result = array_map(fn($value) => is_numeric($value), $inputs);
echo json_encode($result), PHP_EOL;[true,true,false,false,false]
Only the first two entries pass.
Example 3: Filtering before arithmetic
A common use is skipping bad entries when totalling a list of loose values. Adding 0 to a numeric string yields an int or float depending on its format.
function sumNumeric(array $items): int|float {
$total = 0;
foreach ($items as $item) {
if (is_numeric($item)) {
$total += $item + 0;
}
}
return $total;
}
echo json_encode([sumNumeric(["10", "2.5", "x", null, 4]), sumNumeric(["a", ""])]), PHP_EOL;[16.5,0]
The first call adds 10, 2.5 and 4 and skips the rest. The second call finds nothing numeric and returns 0.
Edge cases
- Float special values: any value of type
floatis numeric, includingNANandINF. The strings"NAN"and"INF"are not numeric. - Signs: a single leading
+or-is accepted in a string, so"+5"and"-5"pass. - Exponent notation:
"1337e0"is numeric, but"1e"is not. - Leading zeros:
"02471"is numeric and is read as decimal, not octal. - Alternate bases:
"0x539"and"0b101"as strings fail, even though the same literals written in source code are valid integers. - Empty or blank strings:
""fails, and a string made only of spaces fails as well.
Common mistakes
- Using it to check for integers.
is_numeric("2.5")istrue. If you need whole numbers only, useis_int()for real integers,ctype_digit()for digit-only strings, orfilter_var()withFILTER_VALIDATE_INT. - Assuming the value was converted. The function only inspects it. A string that passes is still a string until you cast it or do arithmetic on it.
- Treating booleans or
nullas zero. They are not numeric for this function, even though they convert to1or0in arithmetic. - Expecting source-literal syntax to work in strings. Hex, octal-prefix and binary notation do not apply to numeric strings.
- Forgetting range concerns. A very long digit string can still be numeric, but it converts to a
floatand may lose precision. - Relying on old whitespace behaviour. Code written for PHP 7 may have assumed that
"42 "fails. In PHP 8.4 it passes, so trim or validate separately if your rules differ.
Related functions
is_int()andis_float()check the actual type of a value.is_string(),is_bool(),is_null()andis_array()check other types.ctype_digit()checks that a string consists only of digit characters.filter_var()validates and converts with filters such asFILTER_VALIDATE_INTandFILTER_VALIDATE_FLOAT.
Recap
is_numeric() takes any value and returns a bool. It accepts integers, floats and well-formed numeric strings, including signs, decimals, exponents and surrounding whitespace in PHP 8 and later. It rejects hex and binary strings, empty strings, null, booleans and arrays. Use it to screen loose input, but reach for is_int(), ctype_digit() or filter_var() when you need stricter rules.
Tested examples
$values = ["42", "-3.14", "1e3", ".5", 10, 2.5, "0x1A", "abc", "", null, true];
$result = [];
foreach ($values as $value) {
$result[] = is_numeric($value);
}
echo json_encode($result), PHP_EOL;[true,true,true,true,true,true,false,false,false,false,false]
$inputs = [" 42", "42 ", "42abc", "4 2", "\u{A0}9001"];
$result = array_map(fn($value) => is_numeric($value), $inputs);
echo json_encode($result), PHP_EOL;[true,true,false,false,false]
function sumNumeric(array $items): int|float {
$total = 0;
foreach ($items as $item) {
if (is_numeric($item)) {
$total += $item + 0;
}
}
return $total;
}
echo json_encode([sumNumeric(["10", "2.5", "x", null, 4]), sumNumeric(["a", ""])]), PHP_EOL;[16.5,0]