Checking that the get value is an integer (whole number) - php

I'm currently building a room booking system and was wondering how to check if the user has correctly entered an integer i.e. 0,1,2,3,4,5 on the form and not anything else (i.e. left it blank, entered decimal number or alphabet).
$capacity = $_GET["capacity"];
Thanks in advance!

As per comments check the post variable is set first, else a warning is raised in recent PHP versions:
isset($_GET['capacity'])
Hence, you can:
Cast it to an int:
$capacity = isset($_GET['capacity']) ? (int)$_GET['capacity'] : null
Use a function:
$capacity = is_numeric($_GET['capacity']) ? (int)$_GET['capacity'] : null;
// cast to int as is_numeric will return floats too
Make it a number and compare against original input:
$capacity = ((int)$_GET['capacity']) == $_GET['capacity']) ? $_GET['capacity'] : null;
This last is ideal in situations where the input might exceed MAX_INT or be altered by casting in some other way.

preg_match('/^[0-5]$/', $_GET['capacity']);
If not just limited from 0 to 5,
preg_match('/^[0-9]+$/', $_GET['capacity']);

this is a filtering job, so a good option is to use the filter module (http://php.net/filter)
so you might use filter_var or filter_input with FILTER_VALIDATE_INT as a flag and compare the result to false (strict comparison, to avoid confusion caused by 0)

I have a different approach if you like:
$validValues=array('0','1','2','3','4','5');
$capacity = $_GET["capacity"];
$isValid=in_array($capacity,$validValues); //TRUE if entered value is in the valid values.
Values read from the $_GET are strings anyway.
PHP manual: in_array()

Check out is_numeric function.

Use regular expression to match for a whole number
preg_match('/^[0-9]\d*$/', $variable)

if($_GET["capacity"] >= 0 && $_GET["capacity"] < 5)
{
//prefect
}
else
{
//invalid
}

Related

Need exact reason for this logically condition failed

Why below code is printing the "here", it should be "there"
$a = "171E-10314";
if($a == '0')
{
echo "here";
}
else
{
echo "there";
}
PHP automatically parses anything that's a number or an integer inside a string to an integer. "171E-10314" is another way of telling PHP to calculate 171 * 10 ^ -10314, which equates to (almost) 0. So when you do $a == '0', the '0' will equate to 0 according to PHP, and it returns true.
If you want to compare strings, use the strcmp function or use the strict comparator ===.
when you use the == comparison, PHP tries to cast to different data types to check for a match like that
in your case:
'0' becomes 0
"171E-10314" is still mathematically almost 0 but I think PHP just rounds it to 0 due to the resolution of float.
check this link for a visual representation:
http://www.wolframalpha.com/input/?i=171E-10314
As per the answers given I tried to convert the string into numerical:
$a = "171E-10314" + 0;
print $a;
And I got output as 0.
Thats why it is printing here.
Use === /*(this is for the 30 character)*/

PHP: issue with comparing variables

I have two PHP variables that can either be empty (i.e. value="") or contain a name in the format Last, First with a comma and a space between the last and first name (e.g. Mouse, Mickey).
I would like to make a simple check here and say if a variable is not empty AND is equal to another then check a checkbox but this doesnt work.
Can someone here show me what I am doing wrong (in the below example the checkbox should be checked) ?
My problem is that the checkbox always gets checked, even if the variables don't match.
Example:
$poc1 = "Mouse, Mickey"; // hard-coded for testing
$poc2 = "Mouse, Mickey"; // hard-coded for testing
<input type="checkbox" id="check2" name="Copy_POC" <?php if(($poc2 != "") && (strcmp($poc2,$poc1))) { echo "checked"; } ?> />
Many thanks for any help with this, Tim.
You need to look at the function signature for strcmp, and its return values:
int strcmp ( string $str1 , string $str2 )
So the function returns an int, but what kind of int? According to the manual:
Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
In other words: if both strings are equal, strcmp returns 0, which evaluates to false. What you should've written therefore is:
strcmp($str1, $str2) !== 0
This will evaluate to true if the 2 strings do not match. Of course, you only want to see the ckeckbox checked when the two strings don't match:
if ($str1 != '' && strcmp($str1, $str2) === 0)
{
//checked
}
That ought to do it. Of course, this still relies on your calling functions to check these strings being equal. That doesn't really add up, though, and it might be a lot easier to just write:
if ($str1 && $str1 === $str2)
//an empty string is falsy + type & value check on 2 strings using === operator
Note
As you may already know, PHP is built on C, and therefore has a lot of C-like str* functions. Whenever you see a function like strcmp and strstr, check its return value. Like the C string.h functions, it often returns either a pointer (part of the string where substring is found, like strstr), or an integer (index/offset in string)...
<?php if($poc2 && $poc2 === $poc1) echo "checked" ?>

How to check in PHP if a string can be transformed to integer?

I have strings of the following form: "37", "42", "7".
I need to transform them into integers. I can use intval. But I want to check if the string was in the expected format (by not expected format I mean, for example, "abc" or "a7"). How can I do it before or after use of the intval?
As far as I know intval returns 1 if the argument was not in the appropriate format. If it is the case, there is not way to check if the argument was the good format just by analyzing the output of the intval.
You can use
ctype_digit()
http://ro2.php.net/ctype_digit
You're probably looking for filter_var.
$input = '5';
filter_var($input, FILTER_VALIDATE_INT); // returns 5
$input = 'asdf';
filter_var($input, FILTER_VALIDATE_INT); // returns false
There are also many other options you can pass into this function. I believe it was designed as a way to validate form submissions.
ctype_digit($x) && ($x == floor($x))
You can use the function is_numeric(). It should return true if it is a number, false if there are letters in the mix.
Mediocre solution, but you could do:
preg_match('/^[0-9]*$/', $value)
How about (int)$value == $value?
This would cast the value to an int, so that the left hand is definately an integer, and then checks if an untyped comparison is true.

is_int and GET or POST

Why does is_int always return false in the following situation?
echo $_GET['id']; //3
if(is_int($_GET['id']))
echo 'int'; //not executed
Why does is_int always return false?
Because $_GET["id"] is a string, even if it happens to contain a number.
Your options:
Use the filter extension. filter_input(INPUT_GET, "id", FILTER_VALIDATE_INT) will return an integer typed variable if the variable exists, is not an array, represents an integer and that integer is within the valid bounds. Otherwise it will return false.
Force cast it to integer (int)$_GET["id"] - probably not what you want because you can't properly handle errors (i.e. "id" not being a number)
Use ctype_digit() to make sure the string consists only of numbers, and therefore is an integer - technically, this returns true also with very large numbers that are beyond int's scope, but I doubt this will be a problem. However, note that this method will not recognize negative numbers.
Do not use:
is_numeric() because it will also recognize float values (1.23132)
Because HTTP variables are always either strings, or arrays. And the elements of arrays are always strings or arrays.
You want the is_numeric function, which will return true for "4". Either that, or cast the variable to an int $foo = (int) $_GET['id']...
Checking for integers using is_int($value) will return false for strings.
Casting the value -- is_int((int) $value) -- won't help because strings and floats will result in false positive.
is_numeric($value) will reject non numeric strings, but floats still pass.
But the thing is, a float cast to integer won't equal itself if it's not an integer. So I came up with something like this:
$isInt = (is_numeric($value) && (int) $value == $value);
It works fine for integers and strings ... and some floating numbers.
But unfortunately, this will not work for some float integers.
$number = pow(125, 1/3); // float(5) -- cube root of 125
var_dump((int) $number == $number); // bool(false)
But that's a whole different question.
How i fixed it:
$int_id = (int) $_GET["id"];
if((string)$int_id == $_GET["id"]) {
echo $_GET["id"];
}
It's probably stored as a string in the $_GET, cast it to an int.
Because $_GET is an array of strings.
To check if the get parameter contains an integer you should use is_numeric()
Because $_GET['id'] is a string like other parts of query string. You are not converting it to integer anywhere so is_int return false.
The dirty solution I'm using is this:
$val = trim($_GET['id']);
$cnd = ($val == (int)$val);
echo $cnd ? "It's an int" : "Not an int";
Apart from the obvious (ugly code that hides its workings behind specifics of the php engine), does anybody know cases where this goes wrong?
Prabably best way to check if value from GET or POST is integer is check by preg_match
if( preg_match('/^[0-9]+$/', $_GET['id'] ){
echo "is int";
}
You can possibly try the intval() which can be used to test the value of your var. e.g
If(intval($_GET['ID']==0)
The function will check if the var is integer and return TRUE if not FALSE

String comparison using '==' or '===' vs. 'strcmp()'

It seems that PHP's === operator is case sensitive. So is there a reason to use strcmp()?
Is it safe to do something like the following?
if ($password === $password2) { ... }
The reason to use it is because strcmp
returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
=== only returns true or false, it doesn't tell you which is the "greater" string.
You should never use == for string comparison. === is OK.
$something = 0;
echo ('password123' == $something) ? 'true' : 'false';
Just run the above code and you'll see why.
$something = 0;
echo ('password123' === $something) ? 'true' : 'false';
Now, that's a little better.
Don't use == in PHP. It will not do what you expect. Even if you are comparing strings to strings, PHP will implicitly cast them to floats and do a numerical comparison if they appear numerical.
For example '1e3' == '1000' returns true. You should use === instead.
Well...according to this PHP bug report, you can even get 0wned.
<?php
$pass = isset($_GET['pass']) ? $_GET['pass'] : '';
// Query /?pass[]= will authorize user
//strcmp and strcasecmp both are prone to this hack
if ( strcasecmp( $pass, '123456' ) == 0 ){
echo 'You successfully logged in.';
}
?>
It gives you a warning, but still bypass the comparison.
You should be doing === as #postfuturist suggested.
Always remember, when comparing strings, you should use the === operator (strict comparison) and not == operator (loose comparison).
Summing up all answers:
== is a bad idea for string comparisons.
It will give you "surprising" results in many cases. Don't trust it.
=== is fine, and will give you the best performance.
strcmp() should be used if you need to determine which string is "greater", typically for sorting operations.
Using == might be dangerous.
Note, that it would cast the variable to another data type if the two differs.
Examples:
echo (1 == '1') ? 'true' : 'false';
echo (1 == true) ? 'true' : 'false';
As you can see, these two are from different types, but the result is true, which might not be what your code will expect.
Using ===, however, is recommended as test shows that it's a bit faster than strcmp() and its case-insensitive alternative strcasecmp().
Quick googling yells this speed comparison: http://snipplr.com/view/758/
strcmp() and === are both case sensitive, but === is much faster.
Sample code: Speed Test: strcmp vs ===
strcmp will return different values based on the environment it is running in (Linux/Windows)!
The reason is the that it has a bug as the bug report says - Bug #53999strcmp() doesn't always return -1, 0, or 1
You can use strcmp() if you wish to order/compare strings lexicographically. If you just wish to check for equality then == is just fine.
Also, the function can help in sorting. To be more clear about sorting. strcmp() returns less than 0 if string1 sorts before string2, greater than 0 if string2 sorts before string1 or 0 if they are the same. For example
$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string, $second_string);
The function will return greater than zero, as aaao is sorting before aabo.
if ($password === $password2) { ... } is not a safe thing to do when comparing passwords or password hashes where one of the inputs is user controlled.
In that case it creates a timing oracle allowing an attacker to derive the actual password hash from execution time differences.
Use if (hash_equals($password, $password2)) { ... } instead, because hash_equals performs "timing attack safe string comparison".
In PHP, instead of using alphabetical sorting, use the ASCII value of the character to make the comparison.
Lowercase letters have a higher ASCII value than capitals. It's better to use the identity operator === to make this sort of comparison. strcmp() is a function to perform binary safe string comparisons. It takes two strings as arguments and returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. There is also a case-insensitive version named strcasecmp() that first converts strings to lowercase and then compares them.

Categories