cant progress with php 5 integer passing from a page - php

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)){

Related

isset() returns true from a string variable accessed as an array with any key

I face a problem like this:
$area="Dhaka";
isset($area); //returns true which is OK
isset($area['division']); //returns true why?
// actually, any array key of area returns true
isset($area['ANY_KEY']);//this is my question 1
isset($area['division']['zilla');//now it returns false.
//as I know it should returns false but why previous one was true.
Now if I do this:
$area['division'] = "Dhaka";
isset($area); // returns true which is OK
isset($area['division']); // returns true it's also OK
isset($area['ANY_KEY']); // returns false. I also expect this
isset($area['division']['ANY_KEY']); // returns true why? question #2
Basically both of my questions are the same.
Can anyone explain this?
As with every programming language in existence, a string is stored as an array of characters.
If I did:
$area = "Dhaka";
echo $area[0];
It would return D.
I could also echo the whole string by doing:
echo $area[0].$area[1].$area[2].$area[3].$area[4];
PHP will also type juggle a string into 0 when passed in a manner that accepts only integers.
So by doing:
echo $area['division'];
You would essentially be doing:
echo $area[0];
and again, getting D.
That's why isset($area['division']) returns a true value.
Why doesn't $area['foo']['bar'] (aka $area[0][0]) work? Because $area is only a single-dimension array.
The best approach to handle this problem when you're working with a variable that could either be a string or an array is to test with is_array() before trying to treat your variable as an array:
is_array($area) && isset($area['division'])
PHP lets you treat a string as an array:
$foo = 'bar';
echo $foo[1]; // outputs 'a'
So
$area['division']
will be parsed/executed as
$area[0];
(the keys cannot be strings, since it's not REALLY an array, so PHP type-converts your division string by its convert-to-int rules, and gives 0), and evaluate to the letter D in Dhaka, which is obviously set.
Okay, here's a solution rather than explaining why isset isn't going to work properly.
You want to check if an array element is set based on it's index string. Here's how I might do it:
function isset_by_strkey($KeyStr,$Ar)
{
if(array_key_exists($KeyStr,$Ar))
{
if(strlen($Ar[$KeyStr]) > 0 || is_numeric($Ar[$KeyStr] !== FALSE)
{
return TRUE;
}
return FALSE;
}
}
isset_by_strkey('ANY_KEY',$area); // will return false if ANY_KEY is not set in $area array and true if it is.
The best way to access a linear array in php is
// string treated as an linear array
$string= "roni" ;
echo $string{0} . $string{1} . $string{2} . $string{3};
// output = roni
It is expected behaviour.
PHP Documentation covers this
You can try empty() instead.
If it is returning true for keys that do not exist there's nothing you can do; however, you can make sure that it doesn't have a negative effect on your code. Just use array_key_exists() and then perform isset() on the array element.
Edit: In fact, using array_key_exists() you shouldn't even need isset if it is misbehaving just use something like strlen() or check the value type if array_key_exists returns true.
The point is, rather than just saying isset($Ar['something']) do:
if(array_key_exists('something',$Ar) )
and if necessary check the value length or type. If you need to check the array exists before that of course use isset() or is_array() on just the array itself.

In PHP, can I differentiate the result of intval(null) from intval("0")?

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

Ensuring the information after ? is an integer

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.
}

is_int() cannot check $_GET in PHP?

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
}

How to check if a PHP array has any value set?

I am working on a signup form, I am using PHP and on my processing part I run some code, if a submitted item fails I then add it to an errors array.
Below is a snip of the code, I am at the point where I need to find the best method to determine if I should trigger an error.
So if there is a value set in the error array then I need to redirect and do some other stuff.
I was thinking of using isset or else is_array but I don't think that is the answer since I set the array using **$signup_errors = array()** wouldn't this make the is_array be true?
Can anyone suggest a good way to do this?
//at the beginning I set the error array
$signup_errors = array();
// I then add items to the error array as needed like this...
$signup_errors['captcha'] = 'Please Enter the Correct Security Code';
if ($signup_errors) {
// there was an error
} else {
// there wasn't
}
How does it work? When converting to boolean, an empty array converts to false. Every other array converts to true. From the PHP manual:
Converting to boolean
To explicitly convert a value to
boolean, use the (bool) or (boolean)
casts. However, in most cases the cast
is unncecessary, since a value will be
automatically converted if an
operator, function or control
structure requires a boolean argument.
See also Type Juggling.
When converting to boolean, the
following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
You could also use empty() as it has similar semantics.
Perhaps empty()?
From Docs:
Return Values
Returns FALSE if var has a non-empty
and non-zero value.
The following things are considered to
be empty:
"" (an empty string)
0 (0 as an integer)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)
Check if...
if(count($array) > 0) { ... }
...if it is, then at least one key-value pair is set.
Alternatively, check if the array is not empty():
if(!empty($array)) { ... }
Use array_filter if you already have keys, but want to check for non-boolean evaluated values.
<?php
$errors = ['foo' => '', 'bar' => null];
var_dump(array_filter($errors));
$errors = ['foo' => 'Oops', 'bar' => null];
var_dump(array_filter($errors));
Output:
array(0) {
}
array(1) {
["foo"]=>
string(4) "Oops"
}
Use:
<?php
if(array_filter($errors)) {
// Has errors
}
You could check on both the minimum and maximum values of the array, in this case you can have a large array filled with keys and empty values and you don't have to iterate through every key-value pair
if(!min($array) && !max($array)) { ... }
The language construct isset(), is for testing to see if variables and array elements are set and not NULL. Using is_array() would tell you if the argument you supply to it is an array. Thus, I do not think using isset() or is_array() would give you the correct and desired result that you are seeking.
The code:
$signup_errors = array();
means that ...
is_array($signup_errors);
would return true. However, this does not mean that the Boolean language rules of PHP would evaluate....
if($signup_errors)
{
//*Do something if $signup_errors evaluates to true*;
}
as true, unless some elements are added to it. When you did this,
$signup_errors['captcha'] = 'Please Enter the Correct Security Code';
you fulfilled the PHP language requirement for the array above to evaluate to true.
Now, if for some reason you wanted, or needed, to use isset() on the array elements in the future, you could. But, the conditional statement above is enough for you this case.
I should add an obvious answer here. If you initialise your error array as an empty array. And later want to check if it is no longer an empty array:
<?php
$errors = [];
if($errors !== [])
{
// We have errors.
}

Categories