intval 还是 is_numeric? PHP

Posted

技术标签:

【中文标题】intval 还是 is_numeric? PHP【英文标题】:intval or is_numeric? PHP 【发布时间】:2009-09-04 20:22:06 【问题描述】:

我正在从 mysql 数据库中获取文本,并通过 url 中的 ID 获取它:

site.php?id=1 等等

什么被认为是最安全的,以防止 sql 注入和东西。这种方式是否正确:

<?php
$news_id = $_GET['news_id'];

if(!is_numeric($news_id)) die('Wrong');

//mysql_query and stuff here
?>

或者这样:

<?php
$news_id = $_GET['news_id'];

if(!intval($news_id)) die('Wrong');

//mysql_query and stuff here
?>

【问题讨论】:

对 is_numeric 的一点说明,它允许使用十六进制字符(从安全角度来看,这没什么大不了的)。如果你真的想检查一个数值,请使用 ctype_digit,确保输入一个字符串,而不是 int:ctype_digit ( (int) 123 ); // false ctype_digit ('123'); // 是的 【参考方案1】:

为什么不直接使用prepared statement,这才是应对sql注入攻击的正确方式。

但是,使用 intval 将字符串转换为整数,然后将其放入准备好的语句中,您将受到保护,因为 int 值可能为零或负数,因此您的查询不会返回任何内容.

【讨论】:

【参考方案2】:
$news_id = (int)@$_GET['news_id'];
if ($news_id <= 0) die ('Wrong');

假设news_id 是正数 (>0)。

【讨论】:

【参考方案3】:

如果您使用 intval,您将无法使用 news_id=0,因为如果 news_id 不是数字,intval 将始终返回 0。 is_numeric 在您的情况下更合适且更安全。

【讨论】:

很有可能,news_id 是一个永远不会包含 0 的生成列。如果是这样,那么在查询中使用 intval( $id ) 并没有什么坏处;如果请求包含错误的标识符,那么您最终将显示“未找到”错误,这对于错误的请求是完全可以接受的。或者,当然,如果 0 是一个从未使用过的值,那么您可以测试输出并抛出一个不同的错误(“请提供有效的标识符”)拒绝请求。【参考方案4】:
if (preg_match("/^[1-9]+\d*$/", $news_id))
    // you're good to go

【讨论】:

这不包括前导0s,包括“0”。这是故意的吗?另外,+ 也没用。【参考方案5】:

is_numeric 不是检查它的好方法,

$number = "4"; // string ? int ?

intval 不返回真或假。所以你不能像你写的那样使用它。 试试这个

if(intval($news_id) === (int)$news_id)
//code goes here

if(intval($news_id) == $news_id)
//code goes here

【讨论】:

您的身份证号码的合法范围是多少?它是从零开始还是从一开始? 这个答案是完全错误的,没有int_val这样的功能 @Traveling_Monk 冷静一下,我的意思是 intval 但只是一个错字。

以上是关于intval 还是 is_numeric? PHP的主要内容,如果未能解决你的问题,请参考以下文章

PHP判断是否为数字型或是否为数字型字符串

回声不能在 PHP 中为 !is_numeric 工作

php读取excel时间42930转化为时间然后正则验证时间是否通过

preg_match()漏洞

is_numeric()

is_numeric($str) 用于数据库查询