This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the correct way to test if a variable is a number in PHP?
I have two variables coming in from a form:
$minNo = mysql_real_escape_string($_GET["minNo"]);
$maxNo = mysql_real_escape_string($_GET["maxNo"]);
How can I check whether they are numerical values or not?
Try is_numeric.
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 notation (0xFF) is allowed too but only without sign,
decimal and exponential part.
Use is_numeric function, it returns bool value:
is_numeric($element)
You can use is_numeric() to check if the number is numeric.
To validate as an integer, use...
$validInt = filter_var($minNo, FILTER_VALIDATE_INT);
using is_numeric() function...
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Regular expression to limit number of characters to 10
I retrieve a POST to a standard form and I need to test two things:
The value must be 40 characters
The value must contain only letters and numbers
I think it is possible to do this with preg_match, but I do not know how.
In the global $_POST you have all your posted data on the http request.
then:
$myvar = $_POST['your_posted_variable_here'];
$result = preg_match('/^([\w\d]){40}$/i', $myvar);
$result will be true if your posted data only contains letters and digits and is 40 characters long, otherwise will be false.
For exactly 40 characters:
^[a-zA-Z0-9]{40}$
For at least 40 characters:
^[a-zA-Z0-9]{40,}$
Information on preg_match
http://php.net/manual/en/function.preg-match.php
if (preg_match("#^[a-z0-9]{40}$#mis", $_POST['username'])) {
print 'matched';
}
You can also check the length of the string using strlen() first, then if it satisfies the desired length, go forth with the checking of alpha numerics.
But General has the right idea...
Here's another way:
preg_match("/^[0-9a-zA-Z_]{40,}$/", $_POST["something"])
This is alpha numeric, and checks for at least 40 characters, but will accept more. The missing value after the comma means that it can be of any value equal or bigger than 40.
PHP provides a function for checking alphanumeric characters ctype_alnum and strlen to check the length of a string so using both functions you can validate it
$yourInput=$_POST['yourInput'];
if(ctype_alnum($yourInput) && strlen($strlen)==40)
{
//...
}
This isn't a big issue for me (as far as I'm aware), it's more of something that's interested me. But what is the main difference, if any, of using is_numeric over preg_match (or vice versa) to validate user input values.
Example One:
<?php
$id = $_GET['id'];
if (!preg_match('/^[0-9]*$/', $id)) {
// Error
} else {
// Continue
}
?>
Example Two:
<?php
$id = $_GET['id'];
if (!is_numeric($id)) {
// Error
} else {
// Continue
}
?>
I assume both do exactly the same but is there any specific differences which could cause problems later somehow? Is there a "best way" or something I'm not seeing which makes them different.
is_numeric() tests whether a value is a number. It doesn't necessarily have to be an integer though - it could a decimal number or a number in scientific notation.
The preg_match() example you've given only checks that a value contains the digits zero to nine; any number of them, and in any sequence.
Note that the regular expression you've given also isn't a perfect integer checker, the way you've written it. It doesn't allow for negatives; it does allow for a zero-length string (ie with no digits at all, which presumably shouldn't be valid?), and it allows the number to have any number of leading zeros, which again may not be the intended.
[EDIT]
As per your comment, a better regular expression might look like this:
/^[1-9][0-9]*$/
This forces the first digit to only be between 1 and 9, so you can't have leading zeros. It also forces it to be at least one digit long, so solves the zero-length string issue.
You're not worried about negatives, so that's not an issue.
You might want to restrict the number of digits, because as things stand, it will allow strings that are too big to be stored as integers. To restrict this, you would change the star into a length restriction like so:
/^[1-9][0-9]{0,15}$/
This would allow the string to be between 1 and 16 digits long (ie the first digit plus 0-15 further digits). Feel free to adjust the numbers in the curly braces to suit your own needs. If you want a fixed length string, then you only need to specify one number in the braces.
According to http://www.php.net/manual/en/function.is-numeric.php, is_numeric alows something like "+0123.45e6" or "0xFF". I think this not what you expect.
preg_match can be slow, and you can have something like 0000 or 0051.
I prefer using ctype_digit (works only with strings, it's ok with $_GET).
<?php
$id = $_GET['id'];
if (ctype_digit($id)) {
echo 'ok';
} else {
echo 'nok';
}
?>
is_numeric() allows any form of number. so 1, 3.14159265, 2.71828e10 are all "numeric", while your regex boils down to the equivalent of is_int()
is_numeric would accept "-0.5e+12" as a valid ID.
Not exactly the same.
From the PHP docs of is_numeric:
'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric
With your regex you only check for 'basic' numeric values.
Also is_numeric() should be faster.
is_numeric checks whether it is any sort of number, while your regex checks whether it is an integer, possibly with leading 0s. For an id, stored as an integer, it is quite likely that we will want to not have leading 0s. Following Spudley's answer, we can do:
/^[1-9][0-9]*$/
However, as Spudley notes, the resulting string may be too large to be stored as a 32-bit or 64-bit integer value. The maximum value of an signed 32-bit integer is 2,147,483,647 (10 digits), and the maximum value of an signed 64-bit integer is 9,223,372,036,854,775,807 (19 digits). However, many 10 and 19 digit integers are larger than the maximum 32-bit and 64-bit integers respectively. A simple regex-only solution would be:
/^[1-9][0-9]{0-8}$/
or
/^[1-9][0-9]{0-17}$/
respectively, but these "solutions" unhappily restrict each to 9 and 19 digit integers; hardly a satisfying result. A better solution might be something like:
$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
echo 'ok';
} else {
echo 'nok';
}
is_numeric checks more:
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 notation (0xFF) is allowed too but only without sign,
decimal and exponential part.
You can use this code for number validation:
if (!preg_match("/^[0-9]+$/i", $phone)) {
$errorMSG = 'Invalid Number!';
$error = 1;
}
If you're only checking if it's a number, is_numeric() is much much better here. It's more readable and a bit quicker than regex.
The issue with your regex here is that it won't allow decimal values, so essentially you've just written is_int() in regex. Regular expressions should only be used when there is a non-standard data format in your input; PHP has plenty of built in validation functions, even an email validator without regex.
PHP's is_numeric function allows for floats as well as integers. At the same time, the is_int function is too strict if you want to validate form data (strings only). Therefore, you had usually best use regular expressions for this.
Strictly speaking, integers are whole numbers positive and negative, and also including zero. Here is a regular expression for this:
/^0$|^[-]?[1-9][0-9]*$/
OR, if you want to allow leading zeros:
/^[-]?[0]|[1-9][0-9]$/
Note that this will allow for values such as -0000, which does not cause problems in PHP, however. (MySQL will also cast such values as 0.)
You may also want to confine the length of your integer for considerations of 32/64-bit PHP platform features and/or database compatibility. For instance, to limit the length of your integer to 9 digits (excluding the optional - sign), you could use:
/^0$|^[-]?[1-9][0-9]{0,8}$/
Meanwhile, all the values above will only restrict the values to integer,
so i use
/^[1-9][0-9\.]{0,15}$/
to allow float values too.
You can use filter_var() to check for integers in strings
<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
echo $intnum.' is an int now';
}else{
echo "$intnum is not an int.";
}
// will output 1000022 is an int now
is_int($_GET['pid']) ? define(PRODUCT, $_GET['pid']) : die('Invalid Product Id');
even if the value of pid is an integer I still get the Invalid product id message. Why?
Like the manual says: To test if a variable is a number or a numeric string (such as form input, which is always a string), you must use is_numeric().
Edit: Though it's implied by my answer here, I'll be more specific: $_GET's contents is strings, so an is_int call will always return false. If what you really want to verify here is that the contents of a particular string represents a integer number, you can use a call to is_numeric.
values in the $_GET array are usually type string, but sometimes type array as well.
use ctype_digit() to check if a string is entirely digit characters. optionally, trim() the string first. only use is_numeric() if you want to accept strings in a wide range of formats that are sometimes interpreted numerically, such as decimals, scientific notation, hex strings etc...
$_GET[] always returns strings, so is_int() always evaluates to false. Try is_numeric() instead.
Anything in $_GET is string, and is_int("2") returns false.
Why is the output 'in'?
<?php
if (1=='1, 3')
{
echo "in";
}
?>
The == operator does type conversion on the two values to try to get them to be the same type. In your example it will convert the second value from a string into an integer, which will be equal to 1. This is then obviously equal to the value you're matching.
If your first value had been a string - ie '1' in quotes, rather than an integer, then the match would have failed because both sides are strings, so it would have done a string comparison, and they're different strings.
If you need an exact match operator that doesn't do type conversion, PHP also offers a tripple-equal operator, ===, which may be what you're looking for instead.
Hope that helps.
Because PHP is doing type conversion, it's turning a string into an integer, and it's methods of doing so work such that it counts all numbers up until a non-numeric value. In your case that's the substring ('1') (because , is the first non-numeric character). If you string started with anything but a number, you'd get 0.
You are comparing a string and an integer. The string must be converted to an integer first, and PHP converts numeric strings to integers. Since the start of that string is '1', it compares the number one, with the number one, these are equal.
What functionality did you intend?
If you're trying to check if 1 is equal to 1 or 3, then I would definitely do it this way:
if (1 == 1 || 1 == 3)
Please refer to the PHP documentation:
http://php.net/manual/en/language.operators.comparison.php
The output should be:
in
From PHP's documentation:
When converting from a string to an
integer, PHP analyzes the string one
character at a time until it finds a
non-digit character. (The number may,
optionally, start with a + or - sign.)
The resulting number is parsed as a
decimal number (base-10). A failure to
parse a valid decimal number returns
the value 0.
I'm guessing you want to know whether a variable is in a range of values.
You can use in_array:
if (in_array(1, array(1, 3, 5, 6)))
echo "in";
if(in_array(1, array(1,3)) {
echo "in";
}
I read on a forum that you can't completely trust is_numeric(). It lets through "0xFF" for example which is an allowed hexadecimal...
So my question is can you trick is_numeric? Will I need to use a regex to do it correctly?
Here is what is_numeric() considers to be a numeric string:
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 notation (0xFF) is allowed too but only without sign, decimal and exponential part.
If you only want to check if a string consists of decimal digits 0-9, you could use ctype_digit().
One can also check using ctype_digit() to check if its a true number.
Regex would obviously be your better option, however it does come with an overhead. So it really depends on your situation and what you want to do.
Is it for validating user input? Then the overhead of using a regexp or asserting it doesn't contain an "x" and is_numeric() wouldn't be too much overhead.
If you just want to check that something is an integer, try this:
function isInteger($value){
return (is_numeric($value) ? intval($value) == $value : false);
}
If you want to check for floats too then this won't work obviously :)