Here is my code:
<?php
$id = $_GET["id"];
if (is_int($id) === FALSE) {
header('HTTP/1.1 404 Not Found');
exit('404, page not found');
}
?>
It always enters inside the if.
is_int checks that the data type is an integer, but everything in $_GET will be a string. Therefore, it will always return false.
In a pinch, you could cast to an integer and then check for != 0.
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
if (!$id) { // === 0 || === null
header('HTTP/1.1 404 Not Found');
exit('404, page not found');
}
But a more robust solution would involve some type of input string validation / filtering, like PHP's built-in filter_input_array().
(Edited post on Oct/13 since it is still receiving upvotes and it was somewhat confusingly worded.)
User input in $_GET array (as well as the other superglobals) all take the form of strings.
is_int checks the type (i.e. string) of the value, not whether it contains integer-like values. For verification that the input is an integer string, I would suggest either something like ctype_digit or an integer filter (FILTER_VALIDATE_INT—this has the benefit of actually changing the value to type integer). Of course you could also typecast it with (int).
From the PHP documentation for is_int:
Note: 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().
Any user input comes in as a string, because PHP has no way to tell what data type you expect the data to be.
Cast it to an integer or use a regex if you want to make sure it's an integer.
<?php
$id = $_GET["id"];
if ((int) $id == 0) {
header('HTTP/1.1 404 Not Found');
exit('404, page not found');
}
?>
Try using is_numeric instead of is_int. is_numeric checks to see if it is given something that can be a number ($_GET returns strings I think). is_int checks to see if the variable is of type int
Use is_numeric() to evaluate the content and is_int() to evaluate the type.
Or, you could just use a regex match to check if the string is an integer.
if(preg_match('/^\d+$/',$_GET['id'])) {
// is an integer
}
Related
is_int in php 5 doesn't recognize a GET integer when it's passed to it
$blog_ident=$_GET['blog_id'];
if (is_int($blog_ident)){
$sql="SELECT * FROM blog WHERE blog_id='$blog_id'";
$result = mysqli_query($db,$sql);
if (!$result) {
die('Sorry there was a problem reading the blog.');
}
// If we get a result back
while ( $row = $result->fetch_array(MYSQLI_ASSOC) ) {
#extract($row);
}
} else {
die ('Problem with the blog');
}
http://mydomain/blog_edit.php?blog_id=1
This always ends in 'Problem with the blog'. I can't get it to recognize the 1 as an int and proceed to the database query
Values in the $_GET and $_POST super globals are always strings. You may either cast it as an INT or use is_numeric to see if the value is a number.
The problem is in the second line of code, more specifically is_int(...). The docs page for is_int states its functionality as the following:
Find whether the type of a variable is integer
The problem here is that the type of $blog_ident is a string even though the value is a number, because the contents of $_GET is always of the type string. is_int only checks the type of the variable, not its content. If you continue to read on the docs page for is_int you'll find this part.
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().
If you replace is_int($blog_ident) line to the following you should ger the desired result:
if (is_numeric($blog_ident)){
I have a page like so:
http://sitename/gallery.php?page=2
It has pagination links at the bottom by which we can browse. Everytime the page numbers are clicked, it would send a GET request with parameters page=1 or page=2 and so on ...
When I store these values to $page from teh $_GET variable, it is a string value. I can convert it to an integer using (int) like this:
if(!empty($_GET['page'])){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
But how can I make sure that the value passed is an integer only and not other crap?
Using filters:
if (null !== ($page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE))) {
// $page is now an integer
}
This also checks whether the variable appears in the query string at the same time. If you want to differentiate between missing and invalid you have to leave off the last argument to filter_input():
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
// $page can be null (not present), false (present but not valid) or a valid integer
Use filter_var() with the FILTER_VALIDATE_INT filter on it, and check the return value.
Use is_numeric().
is_int() will not work because GET parameters are always string.
I've left a few comments here and there. Thanks to weak typing, functions like empty and isset tend to be unreliable. The quickest way to check if a parameter is an int or not IMO would be this:
if (array_key_exists('page',$_GET) && ($_GET['page'] == (int) $_GET['page']))
Casting to int and then compare the respective values will return true only when $_GET['page'] is a valid int. If you want to use strict type comparison for some reason (some do), you could double cast:
if (array_key_exists('page',$_GET) && ($_GET['page'] === (string)((int) $_GET['page'])))
But in this particular case, I can't really see why you would want to do that
this is a way how to check parameter if it is intetger or not.
if (is_int((int) $_GET['user_id']) && (int) $_GET['user_id'] != 0) {
$user_id = $_GET['user_id'];
}
Using is_int won't help, probably. All incoming parameters (including $_GET and $_POST) are parsed as strings by PHP. The is_int function checks the datatype, not the value. ctype_digit checks for only digits though:
if(isset($_GET['page']) && ctype_digit($_GET['page']){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
if(!empty($_GET['page']) and is_numeric($_GET['page'])){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
is_numeric is probably what you need.
You can also check with
isNAN($_GET['something']);//is_numeric($_GET['something'])
it returns a boolean value(true,flase)....if its true then it is not an integer,if false its an integer.
if (isset($_GET['page']) && (($get_page_filtered = filter_var($_GET['page'], FILTER_VALIDATE_INT)) !== FALSE) {
$get_page_int = $get_page_filtered;
}
#see https://stackoverflow.com/a/41868665/6758130
I get input values via POST, some of them might be ID's referring to other things, and some start at 0. When choosing something with ID 0, or something without a value, is there a method like intval() that returns something more helpful than 0 on failure to parse? Or can I somehow differentiate the result of intval() from the failure to parse?
Example:
echo intval(null); // 0
echo intval("0"); // 0
You can use the filter_var() function to determine the difference:
filter_var(null, FILTER_VALIDATE_INT);
// false
filter_var('0', FILTER_VALIDATE_INT);
// int(0)
You can also add flags to specifically accept hexadecimal and octal values, but I wouldn't recommend that for your case.
Btw, in the more likely case that the variable comes from $_POST, you can also use filter_input():
if (is_int($nr = filter_input(INPUT_POST, 'nr', FILTER_VALIDATE_INT))) {
// $nr contains an integer
}
The reason I'm using is_int() on the result of filter_input is because when nothing is posted, null is returned; using is_int() guards against this issue.
Edit
If the question is really just about null vs '0' you can just compare $var !== null:
if (!is_null($var)) {
// $var is definitely not null
// but it might also be an object, string, integer, float even, etc.
}
You could first check if its a number:
is_numeric($val);
Ok, now go for the solution.
preg_match('/^\d+$/','0') //is true
preg_match('/^\d+$/',NULL) //is false
I have a page like so:
http://sitename/gallery.php?page=2
It has pagination links at the bottom by which we can browse. Everytime the page numbers are clicked, it would send a GET request with parameters page=1 or page=2 and so on ...
When I store these values to $page from teh $_GET variable, it is a string value. I can convert it to an integer using (int) like this:
if(!empty($_GET['page'])){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
But how can I make sure that the value passed is an integer only and not other crap?
Using filters:
if (null !== ($page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE))) {
// $page is now an integer
}
This also checks whether the variable appears in the query string at the same time. If you want to differentiate between missing and invalid you have to leave off the last argument to filter_input():
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
// $page can be null (not present), false (present but not valid) or a valid integer
Use filter_var() with the FILTER_VALIDATE_INT filter on it, and check the return value.
Use is_numeric().
is_int() will not work because GET parameters are always string.
I've left a few comments here and there. Thanks to weak typing, functions like empty and isset tend to be unreliable. The quickest way to check if a parameter is an int or not IMO would be this:
if (array_key_exists('page',$_GET) && ($_GET['page'] == (int) $_GET['page']))
Casting to int and then compare the respective values will return true only when $_GET['page'] is a valid int. If you want to use strict type comparison for some reason (some do), you could double cast:
if (array_key_exists('page',$_GET) && ($_GET['page'] === (string)((int) $_GET['page'])))
But in this particular case, I can't really see why you would want to do that
this is a way how to check parameter if it is intetger or not.
if (is_int((int) $_GET['user_id']) && (int) $_GET['user_id'] != 0) {
$user_id = $_GET['user_id'];
}
Using is_int won't help, probably. All incoming parameters (including $_GET and $_POST) are parsed as strings by PHP. The is_int function checks the datatype, not the value. ctype_digit checks for only digits though:
if(isset($_GET['page']) && ctype_digit($_GET['page']){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
if(!empty($_GET['page']) and is_numeric($_GET['page'])){
$page = (int)$_GET['page'];
echo "Page Number: ".$page;
}
is_numeric is probably what you need.
You can also check with
isNAN($_GET['something']);//is_numeric($_GET['something'])
it returns a boolean value(true,flase)....if its true then it is not an integer,if false its an integer.
if (isset($_GET['page']) && (($get_page_filtered = filter_var($_GET['page'], FILTER_VALIDATE_INT)) !== FALSE) {
$get_page_int = $get_page_filtered;
}
#see https://stackoverflow.com/a/41868665/6758130
I've moved from HTML to PHP coding, so when I wanted to make a link for my news page I used HREF to take the id for the row as a link and make the title of the piece the viewable/clickable link:
echo "<a href=news.php?id=".$row{'id'};
echo ">";
echo ucwords(strtolower($row{'newstitle'}));
echo "</a>";
So when someone clicks on the title it redirects to the article and the address bar becomes (obviously this is an example):
http://site.com/news.php?id=1
How can I validate that the information after the ? is id=int (it will always be a number) and not some user code or other input that could damage the site? I've looked at ways of Sanitizing/Validating the code, but all the examples I've found have been to do with entering information into forms that are then used in the address rather than simply ensuring the address is valid, hence turning to here for assistance.
Thanks
You should use the filter module:
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false) {
// not an integer
}
Or you can use ctype_digit() to check if a variable is composed only of decimal digits:
if (ctype_digit($_GET['id'])) {
// it's an integer
} else {
// not an integer
}
Or shorter:
ctype_digit($_GET['id']) or die("oops that's not an integer!");
But die or exit would make your code less testable.
is_numeric would work too, but it would return true for any string representation of a number, not only integers.
Try this
<?php
if (is_int($_GET["id"])) {
echo "is integer\n";
} else {
echo "is not an integer\n";
}
?>
If you have excluded 0 as a valid number for your integer id, you can simply do the following:
$id = (int) $_GET['id'];
if (!$id) {
# no number -or- 0 given
} else {
# regardless what have been given, it has been converted at least to some integer.
}
That's by casting. Now $id is always an integer so more safe to use.
However, most often you need to check as well that the number is non-negative:
$id = max(0, $_GET['id']);
The max function does take care of casting $_GET['id'] into an integer. It ensures that the id is 0 or higher in case the provided value was greater than 0. If it was 0 or lower, 0 is the maximum number.
If you then need to actually validate the input more strictly, you can turn it back into a string for comparison reasons:
if ("$id" === $_GET['id'])
{
# Input was done as a string representation of the integer value.
}