tags:

views:

83

answers:

5

How do I check and see if a user enters only numbers and is at least 4 numbers long using PHP?

+5  A: 

You could use a regular expression:

/^\d{4,}$/

Example usage:

$s = "7325";
if (preg_match('/^\d{4,}$/', $s)) {
    echo "matches";
}
Mark Byers
Which you can check using `preg_match()`
Alexandre Jasmin
@Alexandre Jasmin, thank you :)
TaG
@Alexandre: Good point - I've added some example code.
Mark Byers
Looks good, assuming you can only have positive numbers.
muddybruin
one thing people often forget when using `$` is that it also matches a new line just before end, so the above will validate `"7325\n"`. To work around this, use D modifier, or `\z` instead of dollar.
stereofrog
A: 

Do you have any example code to start with?

To strictly answer your question, you could use a regex like if(preg_match('/^\d{4,}$/', $input)....

But there's a lot more to consider here: you need to consider both validation and filtering (and you're best to keep the two separate issues). If you're strictly checking for an integer, then I suppose you're safe from SQL injection, XSS, etc., but you really need to have a handle on those issues, because sooner or later you're going to need to filter & validate something other than a simple integer.

keithjgrant
intval('0000') is 0, which would be invalid by yours, even though it's four digits and has length 4 or greater.
notJim
+6  A: 

Mark Byers' suggestion is good, but here's another way:

$valid = ctype_digit($number) && strlen($number) >= 4;
notJim
I like this because (like Mark's) '0123' meets the condition and regex engine is not used.
webbiedave
@notJim, you win my vote because yours in the most performant :)
macek
+1  A: 

ctype_digit() && strlen() wins

<?php

function benchmark($callback){
  echo sprintf('%-30s: ', $callback);
  $t = microtime(true);
  foreach(range(1, 10000) as $n){
    call_user_func($callback);
  }
  echo (microtime(true)-$t)."\n";
}

function mark_byers_preg_match(){
  $s = "7325";
  preg_match('/^\d{4,}$/', $s);
}

function notjim_ctype_digit_strlen(){
  $number = 7325;
  ctype_digit($number) && strlen($number) >= 4;
}

function tomalak_intval_broken(){
  $check = 7325;
  intval($check) == $check && $check >= 1000 && $check <= 9999;
}

benchmark('mark_byers_preg_match');
benchmark('notjim_ctype_digit_strlen');
benchmark('tomalak_intval_broken');

?>

results

mark_byers_preg_match         : 0.029040098190308
notjim_ctype_digit_strlen     : 0.026585817337036
tomalak_intval_broken         : 0.019872903823853

Note: @Tomalak's does not work with numbers starting with 0 so it does not qualify


Edit: @kiethjgrant's solution was removed because intval(0000) evaluates as false when it should be true.

macek
with numbers this close by, there is no winner. Also, since the OP said, this is user input, all input will be strings.
Gordon
I appreciate the effort, but this is the mother of all pointless, premature micro-optimizations.
notJim
@notJim, both "mother of all pointless" and "premature" are moot points. Sometimes the results are drastically different, and it only took about 2 minutes to copy/paste the solutions into the script. What's the harm?
macek
What I mean is that with a difference of .003 seconds for 10000 trials, choosing either option based on these results would be foolish.
notJim
A: 

you should always use the most efficient way to do it

if ( is_numeric($imput) && isset($input[3]) )
{
  // your code
}

isset() is a language construct, which is always faster than strlen().

isset($input[n-1]) tells you whether string(data which passes through form is always string) has at least n long.

is_numeric() checks it is a valid num string.

i think it is better than ctype_digit() && strlen().

wiiman
is_numeric validates much more then just digits.
OIS