2015-04-06 85 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