32

I just want to know the method to check a PHP variable for any non-numbers and if it also detects spaces between characters? Need to make sure nothing weird gets put into my form fields. Thanks in advance.

user701510
  • 5,563
  • 17
  • 61
  • 86
  • Could you provide a bit more detail? Examples of acceptable and unacceptable values? – kapa Jun 09 '11 at 08:57
  • 1
    http://stackoverflow.com/questions/5740371/quickest-way-to-check-that-a-value-in-php-only-contains-digits – Marty Jun 09 '11 at 09:02
  • please use the search function before asking. this has been asked numerous times before. – Gordon Jun 09 '11 at 09:16
  • 2
    Could you be more precise: do you want to make sure the user enter a **numerical value**, or do you want **only digits**? There is a difference. – Matthieu Napoli Jun 09 '11 at 09:21

9 Answers9

39

If you mean that you only want a value to contain digits then you can use ctype_digit().

Marty
  • 39,033
  • 19
  • 93
  • 162
  • 1
    This should be rewritten as, “ […] you only want a value to contain **digits** then you can use `ctype_digit()`”. That function will fail on `1.25` or `-11` which are “numbers”. If the OP wants to check if a value contains a number they should use `is_numeric()`. – Quinn Comendant Jun 17 '15 at 18:35
  • 1
    Be aware `ctype_digit` returns false if you pass it an integer, so if you're using this function to, for example, validate input, then you may want to allow for integers (e.g. from JSON input). You could still use `ctype_digit`, but cast the input to a string first. – Dan. Dec 02 '20 at 10:23
32

You can use is_numeric() :

if ( is_numeric($_POST['foo']) ) {
    $foo = $_POST['foo'];
} else {
    // Error
}

This will check that the value is numerical, so it may contain something else than digits:

12
-12
12.1

But this will ensure that the value is a valid number.

stack
  • 10,280
  • 19
  • 65
  • 117
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
  • 2
    This has advantages over `ctype_digit()` in that it allows decimals and negatives. – mjec Jun 09 '11 at 09:01
  • 4
    `is_numeric()` returns `true` for any numeric value, i.e., it may contain also other characters as long as they describe a number. Possible valid values for `is_numeric()` are: "-1337", "13.37", "13e37", "0x1337". As you can see, they contain non-number characters. – binaryLV Jun 09 '11 at 09:02
  • @mjec, in addition to decimals and negatives, it also allows "positives" (i.e., with "+" sign), exponentials (with "e" letter) and hexidecimals (starting with "0x"). – binaryLV Jun 09 '11 at 09:04
  • @binaryLV yes this is why `is_numeric()` is a better choice to validate the numerical input of the user in a form. – Matthieu Napoli Jun 09 '11 at 09:08
  • 1
    @Matthieu This won't be a good option assuming that **only numeric characters** are allowed (which I've gathered from the question). – Marty Jun 09 '11 at 09:10
  • @Matthieu, I'd say it is worse rather than better. There's no point in allowing user to input "0x55" as a numeric value. As an addition, while such value would be valid for converting to integer in PHP, it is not valid in some databases (e.g., MySQL). – binaryLV Jun 09 '11 at 09:11
19

You can use ctype_digit

eg:

if (!ctype_digit($myString)) {
    echo "Contains non-numbers.";
}
nickf
  • 537,072
  • 198
  • 649
  • 721
  • 2
    `ctype_digit(1)` will return **false**, `ctype_digit("-1.5")` too, so it's better to use `is_numeric()` to handle all variable types. – Matthieu Napoli Jun 09 '11 at 09:02
  • 6
    @Matthieu, it is not *better*, it is *different*. – binaryLV Jun 09 '11 at 09:06
  • 1
    @binaryLV it is *better* for this use case, of course I'm not talking in general... – Matthieu Napoli Jun 09 '11 at 09:09
  • @Matthieu, "this use case" is to "detect any non-numbers" (i.e., any non-numeric character in a variable) - how is `is_numeric()` better than `ctype_digit()` for such case?! – binaryLV Jun 09 '11 at 09:13
  • @Matthieu Looking at this line in the question: "Need to make sure nothing weird gets put into my form fields" I'm assuming that the check needs to make sure there are **nothing but numeric characters** in a field, not make sure the content of a field could possibly evaluate to a number (ie 0x5) – Marty Jun 09 '11 at 09:15
  • @binaryLV well the second part of the question is "*Need to make sure nothing weird gets put into my form fields*", which is a classic problem. So i'm basing my answer mostly on the second part of the question bc I somehow feel that the OP just want to "make sure nothing weird gets put into his form fields" and is not especially looking after a specific case where he want's only numerical character. That's an interpretation of his needs, and maybe I am wrong. – Matthieu Napoli Jun 09 '11 at 09:17
  • @Marty Yes, you are right, though I feel that he's just expressing his need with a start of a [bad] solution (only numerical characters) whereas his need is only "to make sure nothing weird gets put into my form fields" – Matthieu Napoli Jun 09 '11 at 09:18
  • ctype_digit() it better if u wanna check from type data of string. if type data is integer or float just using is_int() or is_numerik() – mamena tech Apr 16 '21 at 17:23
  • it works fine in laravel 7 – ahmed Aug 01 '22 at 19:22
15

This will return true if there are non-numbers in the string. It detects letters, spaces, tabs, new lines, whatever isn't numbers.

preg_match('#[^0-9]#',$variable)
SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
4

This will check whether the input value is numeric or not. Hope this helps

if(!preg_match('#[^0-9]#',$value))
{
    echo "Value is numeric";
}
else
{
    echo "Value not numeric";
}
Amit Mhaske
  • 471
  • 5
  • 10
3

This worked out to be ~30% faster than preg_match for my test cases, while still letting you match any characters you want:

if( $a !== '' && trim($a, ' 1234567890.,') === '' ){
   print("The variable contains only digits, decimal separators and spaces");
}

This simply removes all characters supplied from the string. If the result is an empty string, you know it only contained those characters.

Magnus
  • 17,157
  • 19
  • 104
  • 189
1

Assuming you want only (and only) valid integers and you dont want users to mess up with your data and database with hexadecimal or binary or any other form of numbers then you can always use this method:

if(((string) (int) $stringVariable) === $stringVariable) {
    // Thats a valid integer :p
}
else {
    // you are out of luck :(
}

The trick is simple. It casts the variable of type string to integer type and then casts it back to string. Super fast, Super simple.

For the sake of testing I've prepared a test:

'1337' is pure integer.
'0x539' is not.
'02471' is not.
'0000343' is not.
'0b10100111001' is not.
'1337e0' is not.
'not numeric' is not.
'not numeric 23' is not.
'9.1' is not.
'+655' is not.
'-586' is pure integer.

The only place that this method falls short is on negative numbers, so you need to check that beside this (use ((string) (int) $stringVariable) === $stringVariable && $stringVariable[0] !== "-").

Now I thought that the preg_match method is the best. but in any project that deals with users, speed is an important factor. so I prepared a benchmarking test doing that above test for 500,000 times and the results were amazing:

My own invented method took only:
6.4700090885162
seconds to complete as compared to preg_match which took:
77.020107984543 seconds to complete this test!

1

PHP has the function is_numeric() which may be what you are looking for.

Ed Brown
  • 417
  • 3
  • 10
1

Cast and compare:

function string_contain_number($val)
{
     return ($val + 0 == $val) ? true : false;
}
symcbean
  • 47,736
  • 6
  • 59
  • 94
  • 1
    (Assuming this approach always works) The ternary isn't necessary. `return $val + 0 == $val;` will be the same. – mickmackusa Aug 06 '22 at 06:17