我遇到了一些奇怪的东西,我不知道它为什么会发生!
我有一个像这样的网址:
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');
?>
Run Code Online (Sandbox Code Playgroud)
所以我测试了它,但结果很奇怪,即使我调用这个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...";
?>
Run Code Online (Sandbox Code Playgroud)
结果:
Real String is: abcdefg
The same string as int is: 0
Weird!
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
提前致谢.
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');
?>
Run Code Online (Sandbox Code Playgroud)
或者,更短:
$id = intval($_GET['id']);
$column = ($id > 0) ? "id" : "page_name";
$query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
Run Code Online (Sandbox Code Playgroud)
但是请注意,可能没有设置$ _GET ["id"],这会在代码中引发通知.
最后,但并非最不重要的:在SQL注入:?id=LittleBobby';Drop table users.
编辑正如评论员指出的那样,我的代码中存在一个逻辑缺陷,源于我在phpsh中仅测试它的事实.我使用重构它is_int()以intval和> 0.在Web环境中,$ _GET ["id"]始终是一个字符串; 无论.因此is_int()将永远回归FALSE.