PHP "is_numeric" accepts "E" as a number
Asked Answered
C

5

7

I noticed PHP is_numeric() accepts "E" as a number. I have a string: "88205052E00" and I want the result to be: NOT numeric.

Here is the code which I tested.

<?php

$notnumber = '88205052E00';

if(is_numeric($notnumber)) {
    echo $notnumber . ' is a number';
} else {
    echo $notnumber . ' is NOT a number';
}

?>

The Code above gives result:

88205052E00 is a number

How can I get the result to be: 88205052E00 is NOT a number?

Clavichord answered 19/12, 2018 at 18:59 Comment(7)
E is used in scientific notation, so yes, it is considered a valid number.Empirical
php.net/manual/en/function.ctype-digit.phpMayhem
You might want to look into a regex that checks for non 0-9 characters. And handles decimals . if you need them.Bug
It is a number as long as PHP is concerned (demo).Hemingway
Do you expect negative number or decimals?Pathan
Your request is impossible because 88205052E00 is a number. It is 88205052*10^0 which is exactly 88205052.Babirusa
@Pathan No, I want only to check for digits, negative or decimals are not expected.Clavichord
P
8

I will keep the answer incase it helps but as pointed out there are shortcomings with ctype_digit in that it does not like - or ..

More likely then you want to use ctype_digit which checks if all of the characters in the provided string, text, are numerical.

Where as is_numeric — Finds whether a variable is a number or a numeric string

<?php

$s = "88205052E00";

if(ctype_digit($s)){
    echo "Yes";
} else {
    echo "No";
}

returns no.

Pathan answered 19/12, 2018 at 19:18 Comment(3)
It is good if you want 3948394873281738173172493274871218201832081239183 to return true and false for -1.Dietsche
I knew there was a reason I did not use this before. Working on a tweakPathan
Since I need to check for digits only (I dont need ` - ` or ` . `), this answer solves my problem. Thank you for helping.Clavichord
F
2

E is valid because of floating point numbers (http://php.net/manual/en/language.types.float.php).

If you don't want to allow E for whatever reason, you could check for it independently:

if (strpos(strtolower($notnumber), 'e') === false && is_numeric($notnumber))

This makes sure that there isn't an E and that it is also numeric.

Fuddyduddy answered 19/12, 2018 at 19:3 Comment(1)
Should be ===, not !==Empirical
I
2

Just use a regular expression:

<?php
if (preg_match("/^\-?[0-9]*\.?[0-9]+\z/", $notnumber)) {
    echo "$notnumber is numeric\n";
} else {
    echo "$notnumber is not numeric\n";
}

Results:

   1234 is numeric
1234E56 is not numeric
  -1234 is numeric
  .1234 is numeric
 -.1234 is numeric
 -12.34 is numeric
Inearth answered 19/12, 2018 at 19:7 Comment(2)
Using trim() means that \t\t12345\n\t\t\n (several whitespace characters on either side) is numeric.Auschwitz
Yes, I'd assume the use of trim on the original variable. Probably best not to assume though.Inearth
D
1

Assuming you want to ensure that the string is a valid integer you could use filter_var:

$tests = ['1', '1.1', '1e0', '0x1'];
foreach($tests as $str) {
    $int = filter_var($str, FILTER_VALIDATE_INT);
    if ($int === false) {
        echo $str . ' is not an integer' . PHP_EOL;
    } else {
        echo $str . ' is an integer' . PHP_EOL;
    }
}

Result:

1 is an integer
1.1 is not an integer
1e0 is not an integer
0x1 is not an integer
Dietsche answered 19/12, 2018 at 19:9 Comment(6)
If you just want to check if the variable is an integer, couldn't you just use is_int?Gratulation
No. is_int('1234') returns false.Dietsche
ah, my mistake. I could have sworn there was a built-in for this.Gratulation
I guess that's what filter_var is for.Gratulation
@KodosJohnson There is ctype_digit(), though (and the very interesting first comment on the documentation page).Triglyceride
All functions (including the above) have gotchas. ctype_digit('239284923942734924729749327') is true but obviously it is too big for integer.Dietsche
A
0

Let's check the definition:

Finds whether the given variable is numeric. Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part. Thus +0123.45e6 is a valid numeric value. Hexadecimal (e.g. 0xf4c3b00c) and binary (e.g. 0b10100111001) notation is not allowed.

The relationship with floating point literals is clear but, how does it all relate to integer literals?

The manual doesn't state explicitly what the use cases are but in general it's more a helper tool (to ensure that you can feed stringified data to functions that expect numeric values) than a proper form validator. If input is collected in an environment where 88205052E00 is not expected then it might be a good idea to expect (and generate) localised data and implement a locale-aware solution.

Ankle answered 20/12, 2018 at 8:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.