我遇到了一些奇怪的东西,我不知道为什么会发生这种情况!
我的网址如下:
http://mysite.com/users/ USER_ID
此用户ID可以是INT
,可以是STRING
,就像Facebook页面地址一样,如果你调用带有页面ID的页面加载它,你也可以用页面名称来调用它“my_page_name”
想象一下,用户的ID为1
且其地址为my_name
在我的php页面上我需要查询db,但在此之前我需要知道要查看的列,id
或page_name
所以我带来了这个解决方案:
<?php
$id = $_GET['id'];
$id_inted = intval($_GET['id']);
if($id == $id_inted){
// 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');
?>
所以我测试了它,但结果很奇怪,即使我称这个URL:
http://mysite.com/users/ page_name
发生这种情况:$column = 'id';
我打开了一个新的测试页面:
<?php
$real_string = 'abcdefg';
$string_inted = intval($real_string);
echo "Real String is: " . $real_string . "<br />";
echo "The same string as int is: " . $string_inted . "<br />";
if($real_string == $string_inted) echo "Weird!"; else echo "Fine...";
?>
和结果:
Real String is: abcdefg
The same string as int is: 0
Weird!
为什么会这样?
提前致谢。
答案 0 :(得分:5)
PHP实际上是“有线”的所谓类型杂耍。它是大多数PHP脚本中最容易出错的部分。因此,您应始终保持安全,并使用最强大的检查。例如,intval("twelve")
将返回0,这是一个有效的整数。但也被认为是“假”:print if (intval("one")) ? "yup" : "nope"
将打印“不”。
在这种情况下,使用intval
并结合检查整数是否大于零,应该可以做到这一点:
<?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');
?>
或者,更短:
$id = intval($_GET['id']);
$column = ($id > 0) ? "id" : "page_name";
$query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
但是请注意,可能没有设置$ _GET [“id”],这会在您的代码中引发通知。
最后,但肯定不是最不重要的: SQL-injection :?id=LittleBobby';Drop table users
。
编辑正如评论员指出的那样,我的代码中存在一个逻辑缺陷,源于我在 phpsh 中测试它的事实。我使用is_int()
到intval
和> 0
重构了它。在Web环境中,$ _GET [“id”]始终是一个字符串;无论。因此,is_int()
将始终返回FALSE
。
答案 1 :(得分:4)
要检查是否请求了数值,请使用is_numeric
。
答案 2 :(得分:2)
来自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.
由于==
运算符上的类型杂乱,您的字符串被转换为整数,并且字符串的intval()
返回0
这解释了为什么代码中的$id == $id_inted
评估为true。
如果您使用===
代替==
进行测试,则不会执行任何类型的杂耍。
答案 3 :(得分:2)
对于类型而言,PHP有点奇怪。
基本上,您正在做的是将字符串解析为数字(因此'abcdef'
返回0,因为它根本不是数字),然后将原始字符串与数字进行比较。
现在,我可以看到为什么你会认为它应该是假的,但PHP试图变得聪明。基本上,==
将强制类型,并且如果其中一个值是数字,则几乎总是强制转换为数字。所以它使用你在字符串上进行的相同转换,然后进行比较。
最好使用===
来检查类型。
答案 4 :(得分:1)
成功时var的整数值,或失败时为0。空数组返回0,非空数组返回1.(来自php.net intval()。)
intval('abcdefg')将触发错误,函数返回0。