Welcome to WebmasterWorld Guest from 54.90.204.233

Forum Moderators: coopster & jatar k

Message Too Old, No Replies

Preg match to kill if anything except numbers in the query string

     
3:55 am on Mar 12, 2010 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 2, 2005
posts:505
votes: 0


I am trying to throw an error if the query string has ANYTHING but numbers present.

I've tried a range of different code, but this is my latest and it doesn't seem to work:
if (!preg_match('/[[:^digit:]]/', $_GET['number'])){
echo'You must not enter anything but a digit.';
}


Basically, if someone enters a - or letter (for example), the form stops processing. Any tips on what I'm doing wrong?
7:58 am on Mar 12, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member

joined:Dec 13, 2009
posts:945
votes: 0


if(!preg_match('/[^0-9]+/', $someVaraiable)) {
// Do processing
} else {
// Error
}
2:09 pm on Mar 12, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12548
votes: 2


You had it almost right there, jake66. Except you are doubling your negation. Once in the regular expression and then once again in the reversal of logic. Remove the reversal of logic (the exclamation point) and your test should work as you expect.
if (preg_match('/[[:^digit:]]/', $_GET['number'])) {
2:15 pm on Mar 12, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator jatar_k is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 24, 2001
posts:15756
votes: 0


if (!ctype_digit($_GET['number'])) echo'You must not enter anything but a digit.';

there are a lot of ways to skin this one ;)

is_int would probably work too
2:58 pm on Mar 12, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator coopster is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 31, 2003
posts:12548
votes: 2


careful with is_int ... is_int won't consider a string value as integer even if the string represents an integer value. It will return different results than you expect.
3:39 pm on Mar 12, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator jatar_k is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 24, 2001
posts:15756
votes: 0


sorry I should have mentioned that, thanks coop

is_int(23) true
is_int("23") false
is_int(23.5) false
is_int(true) false
3:44 pm on Mar 12, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member

joined:Dec 13, 2009
posts:945
votes: 0


I believe is_numeric covers floats - Though I've never tried using it on quoted numbers
8:11 pm on Mar 12, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Nov 28, 2004
posts:7999
votes: 0


<oops misread . . . again>

as one who always reverts to regexps, often when I shouldn't, regexps operate on strings. One of the numeric PHP functions should be more appropriate . . .

if (! is_numeric($var)) { // error }

If you want to go the regexp route, [0-9] is identical to \d, but you need the dot for decimal numbers. Don't forget the beginning/ending string delimiters, ^ outside a class means "beginning of string," $ is end.

^ inside a character class means anything NOT these characters.

if (! preg_match('/^[\d\.]+$/',$var)) { // error }

0r

if (! preg_match('/^[0-9\.]+$/',$var)) { // error }

or - and this one's trickier, using the not in the class - "if it matches on anything NOT a digit or dot"

if (preg_match('/^[^\d\.]+$/',$var)) { // error }
9:03 pm on Mar 12, 2010 (gmt 0)

Full Member

10+ Year Member

joined:July 13, 2007
posts:235
votes: 0


One trick I like to use is PHP's intval()/floatval() functions. Cast the input into an integer or float with these functions, then compare its value to an expected range (for instance, database-generated numeric IDs generally start with 1, so you should probably throw out the input if the value is less than 1). If the input string was not numeric, the functions will return false.

$var = intval( $_POST['input'] );
if ( $var > 1 )
{
// valid number, do processing
}
else
{
// invalid number, display error
}
5:25 am on Mar 14, 2010 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 2, 2005
posts:505
votes: 0


Wow, plethora of great examples here. Thanks, guys!

Any chance there's something I'm doing wrong here? Trying to condense some code fragments..

This works:

if(isset($_GET['number'])){
if(!preg_match('/[^0-9]+/', $_GET['number'])) {
$stripped = (int)$_GET['number'];
}else{
echo'You must not enter anything but a digit.';
}
}


This does not:

if(isset($_GET['number'])&& (!preg_match('/[^0-9]+/', $_GET['number']))) {
$stripped = (int)$_GET['number'];
}else{
echo'You must not enter anything but a digit.';
}
}
8:02 am on Mar 14, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member

joined:Dec 13, 2009
posts:945
votes: 0


I'm not sure on this as I've never done it, but I think it's because you don't have a space before the &&.

Try this:

if(isset($_GET['number']) && !preg_match('/[^0-9]+/', $_GET['number'])) {
9:07 pm on Mar 14, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Nov 28, 2004
posts:7999
votes: 0


You've changed gears and are doing the opposite now. :-) From your original post:

I am trying to throw an error if the query string has ANYTHING but numbers present.


You're doing the opposite now, validating with only numbers in the regexp and throwing an error if it doesn't match. Most of the solutions posted are the other way around:

if ([what I don't want is found]) { error; }
else { OK }

The difference is they require slightly different regexps (but still, you should be going with php numeric functions . . . )

You have also raised the point (pun intended) there may be floats/decimal #'s, you need a dot in your regexp.

Your regexp also needs the beginning/ending string delimiters, otherwise it will still pass with abc123def (see my previous post.)

Since you're going with regexps,

if(isset($_GET['number']) and preg_match('/^[\d\.]+$/', $_GET['number'])) {
$stripped = int($_GET['number']);
}
else {
echo 'You must not enter anything but a digit.';
}

OR, because 0-9 and \d are equivalent,

if(isset($_GET['number']) and preg_match('/^[0-9\.]+$/', $_GET['number'])) {
$stripped = int($_GET['number']);
}
else {
echo 'You must not enter anything but a digit.';
}

I've never seen this,

(int)$_GET['number']

See example above, this one's new on me.
9:22 pm on Mar 14, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member

joined:Dec 13, 2009
posts:945
votes: 0


Does it make a difference which way round it's done? If anything, I would have thought looking for anything-not-numbers(and decimal points) and throwing an error on match would be better, because the preg_match doesn't need to check the entire string.
9:27 pm on Mar 14, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 22, 2009
posts:1397
votes: 0


Hey there Rocknbil,


$stripped = (int)$_GET['number'];


From what I have understood doing similar in the past, this just forces the value held by the var to be a whole int. At least that's how I have always been told as it does. ;-p

Cheers,
MRb
10:06 pm on Mar 14, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Nov 28, 2004
posts:7999
votes: 0


Does it make a difference which way round it's done?


Only in that it needs different regexps . . . and that in trying to assist, the solutions on page 1 are trying to address it one way, here, the opposite.

The "stock" statement for validating input: accept what you want and throw everything else away. So just a preference, I'd do the positive match above.

Wait, no I wouldn't. I've be using PHP numeric functions. :-P

From what I have understood doing similar in the past, this just forces the value held by the var to be a whole int.


Isn't that what this does? int($var)

I guess they're equivalent? I have just never seen it in the wild.
8:28 am on Mar 15, 2010 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member

joined:Dec 13, 2009
posts:945
votes: 0


The "stock" statement for validating input: accept what you want and throw everything else away. So just a preference, I'd do the positive match above.

Wait, no I wouldn't. I've be using PHP numeric functions. :-P

Lol, OK, fair enough. With no output from the preg_match I guess it comes down to personal choice in the end.
12:55 pm on Mar 15, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator jatar_k is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:July 24, 2001
posts:15756
votes: 0


I used to use (int) in the old days quite a bit since there were some functions that didn't quite get the dynamic typing right, I don't remember what functions they were as it was 7 or 8 years ago. Another option is to multiply by 1, which I found more reliable in most cases.

[php.net...]
[php.net...]