PHP intval()奇怪的结果

时间:2012-12-08 11:05:06

标签: php

我遇到了一些奇怪的东西,我不知道为什么会发生这种情况!

我的网址如下:

http://mysite.com/users/ USER_ID

此用户ID可以是INT,可以是STRING,就像Facebook页面地址一样,如果你调用带有页面ID的页面加载它,你也可以用页面名称来调用它“my_page_name”

想象一下,用户的ID为1且其地址为my_name 在我的php页面上我需要查询db,但在此之前我需要知道要查看的列,idpage_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!

为什么会这样?

提前致谢。

5 个答案:

答案 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。