PHP intval()奇怪的结果 [英] PHP intval() weird results
问题描述
我遇到了奇怪的事情,我不知道为什么会发生!
我有一个网址,例如:
http://mysite.com/users/ USER_ID
此用户ID可以为INT
,也可以为STRING
,类似于Facebook页面地址,如果您使用具有页面ID的页面加载该页面,也可以使用诸如"my_page_name"的页面名称进行调用/p>
因此,假设一个用户的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!
为什么会这样?
谢谢.
PHP确实与所谓的类型欺骗"连接"在一起.它是大多数PHP脚本中最容易出错的部分.因此,您应始终保持安全,并使用最可靠的检查方法.例如,intval("twelve")
将返回0,这是一个有效的整数.但也被认为是假":print if (intval("one")) ? "yup" : "nope"
会打印"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注入 :?id=LittleBobby';Drop table users
.
编辑正如评论员所指出的那样,我的代码中存在逻辑缺陷,这源于我仅在 phpsh 中对其进行测试的事实.我将其从is_int()
重构为intval
和> 0
.在网络环境中,$ _GET ["id"]始终是一个字符串.无论.因此is_int()
将始终返回FALSE
.
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 could be INT
and could be STRING
, it's something like Facebook page addresses, if you call the page with page ID it loads it, also you could call it with page name like "my_page_name"
So imagine a user which it's ID is 1
and it's address is my_name
On my php page I need query db, but before that I need to know which column to look, id
or page_name
So I came with this solution:
<?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');
?>
So I tested it, but the results is weird, even if I call this URL:
http://mysite.com/users/page_name
This happens: $column = 'id';
I opened a new test page:
<?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...";
?>
and the results:
Real String is: abcdefg
The same string as int is: 0
Weird!
Why this is happening?
Thanks in advance.
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
.
这篇关于PHP intval()奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!