如何在mysqli_stmt_fetch失败时检索默认行?

时间:2011-03-10 18:55:16

标签: php mysql security parameterized-query

我有一个简单的PHP脚本,它根据URL GET参数从MySQL数据库中提取一行,只是一个名为ID的int。

如果GET参数是数据库的无效ID,例如有人输入的数据库中不是行的int,或者他们尝试输入字符或其他内容,我想显示默认记录

以下代码实际上有效,但我觉得这是错误的代码。我只是不确定为什么,或者我应该做什么。我知道我应该在运行数据库查询之前验证ID是否为int,但是当使用无效ID的整数时,这不能解决该怎么做。

所以为了使这个问题成为一个正确的问题,我应该如何从mysqli_stmt_fetch中恢复返回false?

轻松一点,我知道我是个小组: - )

$ID = (int)$_GET["id"];

$query = "SELECT `col1`, `col2`, `col3` FROM `table` WHERE `ID` = ?";

if ($stmt = mysqli_prepare($connection, $query))
{
    mysqli_stmt_bind_param($stmt, "i", $ID);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_bind_result($stmt, $var1, $var2, $var3);
    if (!mysqli_stmt_fetch($stmt))
    {   
        $ID = 1; //A record I know exists and will always exist
        mysqli_stmt_bind_param($stmt, "i", $ID);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $var1, $var2, $var3);
        mysqli_stmt_fetch($stmt);
    }
    mysqli_stmt_close($stmt);
}

好的,所以通过一些反馈和实验,我在PHP中将ID转换为int并将SQL查询更改为:

SELECT `col1`, `col2`, `col3`
FROM `table`
WHERE `ID` = ?
UNION
SELECT `col1`, `col2`, `col3`
FROM `table`
WHERE `ID` = 1
LIMIT 1

这适用于我能想到并且似乎安全的所有情况。任何问题?还有比我更好的东西吗?

2 个答案:

答案 0 :(得分:0)

首先检查char的传入$ ID,然后将其设置为永远不会作为表中ID的值,然后使用查询

SELECT col1, col2, col3 FROM table WHERE ID = :id
union all 
SELECT col1, col2, col3 FROM table WHERE ID = 1 /* may :defaut_id if */
where not exist (select 1 from table WHERE ID = :id)

答案 1 :(得分:0)

假设默认记录有一个id,那么它可以在一个查询中完成:

select ...
from ...
where (id = ?) or (id = $default_id)

只需将默认ID硬编码到查询字符串中即可。