我正在为我一直在开发的游戏创建一个数据库,我需要用户能够杀死对方,所以我设置了这样的表:
...
`alive1` => Player 1's status
`alive2` => Player 2's status
`alive3` => Player 3's status
`alive4` => Player 4's status
...
我需要能够根据具体情况修改数据库中的这些列,并直接使用用户的输入。然而,这样做:
$stmt = $link->prepare("UPDATE `games` SET `alive{$_GET["player"]}`=0 WHERE `id`=?")
易受SQL注入的攻击。有没有一种好的方法可以将列名"绑定"到查询,这样我就可以安全地修改表了?
$_GET["播放器"]的正确输入应该是整数1..4,所以如果需要的话,我想我可以直接检查输入,并确保它是这四种可能性之一,但我希望有一个更优雅的解决方案。这可能会在稍后的另一个项目中再次出现,在该项目中,可能的输入集会大得多,并且对每个情况进行硬编码将非常耗时。
有什么想法吗?
标识符不能绑定到准备好的语句中,因此您应该将它们列入白名单。
通常,对于白名单,您可以创建一个有效标识符数组,并检查传递的标识符是否在列表中。例如:
$validColumns = array('alive1', 'alive2', 'alive3', 'alive4');
$col = 'alive' . $_GET["player"];
$isSafeToUse = in_array($col, $validColumns);
在你的情况下,你可以只是
$id = (int)$_GET["player"];
然后检查CCD_ 1是否在CCD_。
我会使用一个正则表达式/^[1-4]$/
if(preg_match('/^[1-4]$/', $_GET['player'])){
$stmt = $link->prepare('UPDATE `games` SET `alive' . $_GET['player'] . '` =0 WHERE `id`=?');
} else {
die;
}
为了在未来的项目中使用它,您可以将其扩展到/^[0-9]{1,3}$/
,这将允许您接受一个高达999
的数字