I\'m encountering something weird and I don\'t know why it is happening!
I have a URL like:
http://mysite.com/users/USER_ID
this user id
PHP is a little odd when it comes to types.
Basically, what you are doing is parsing the string into a number (so 'abcdef'
returns 0 because it isn't a number at all), then comparing the original string to the number.
Now, I can see why you would assume that it should be false, but PHP tries to be clever. Basically, ==
will coerce types, and almost always coerces to numbers if one of it's values is a number. So it is using the same conversion that you did on the string, then comparing.
It is a better idea to use ===
which also checks types.
From http://php.net/manual/en/language.operators.comparison.php
Example Name Result
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b,
and they are of the same type.
Your string is casted to integer because of type juggling on ==
operator and intval()
of a string returns 0
This explains why $id == $id_inted
in your code evaluates to true.
If you make your test with ===
instead of ==
no type juggling will be performed.
PHP is really "wired" with so called type-juggling. It is the most error-prone part of most PHP-scripts. As such, you should always stay on the safe side and use the most robust check. For example intval("twelve")
will return 0, which is a valid integer. But also considered "false": print if (intval("one")) ? "yup" : "nope"
will print "nope".
In this case, using intval
, in combination with a check if the integer is larger then zero, should do the trick:
<?php
$id = intval($_GET['id']);
if($id > 0){
// The column which I should look into is id
$column = 'id';
}else{
// The column which I should look into is page_name
$column = 'page_name';
}
$query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
?>
Or, shorter:
$id = intval($_GET['id']);
$column = ($id > 0) ? "id" : "page_name";
$query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
Aso note that $_GET["id"] might not be set, which would throw a notice in your code.
And last, but certainly not least: the SQL-injection: ?id=LittleBobby';Drop table users
.
edit As commentor points out, there was a logical flaw in my code, stemming form the fact I tested it in phpsh only. I refactored it from using is_int()
to intval
and > 0
. In a web-environment, $_GET["id"] is always a string; no matter what. Hence is_int()
will always return FALSE
.
To check if numeric value is requested, use is_numeric
.
The integer value of var on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1. (From php.net intval().)
intval('abcdefg') will trigger an error and the function return with 0.