2015-04-06 110 views
0

我创建了一个游戏,我一直在一个数据库,我需要的用户能够杀死对方,所以我已经设置了表所示:可变列的预处理语句

... 
`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 [“player”]的正确输入应该只是一个整数1..4,所以我想我可以直接检查输入,如果需要的话,确保它是这四种可能性之一,但我希望能有更优雅的解决方案。这可能会在稍后的另一个项目中再次出现,其中一组可能的投入会更大,并且对每个案例进行硬编码将非常耗时。

任何想法?

回答

1

标识符不能绑定到准备好的语句中,因此您应该将它们列入白名单。

一般来说,对于白名单,您可以创建一个有效标识符数组,并检查传入的标识符是否在列表中。例如:

$validColumns = array('alive1', 'alive2', 'alive3', 'alive4'); 
$col = 'alive' . $_GET["player"]; 
$isSafeToUse = in_array($col, $validColumns); 

你的情况,你可以

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

,然后检查$id[1, 4]范围。

+0

我明白了,所以我只会做'if($ id> 0和$ id <5)// do statement'? – David

+0

@MathNerdProductions是的。尽管我会用'$ id> = 1 && $ id <= 4'。 – zerkms

+0

好极了。这有很大帮助。谢谢! – David

0

我会用络表达/^[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

+0

'1'lol ok'会通过这张支票。 – zerkms

+0

@zerkms oops fixed – cmorrissey

+0

同时移除'{1,1}' – zerkms