1. 程式人生 > >在PHP中使用 mysqli 並防SQL注入

在PHP中使用 mysqli 並防SQL注入

自從 php5 推出 mysqli 後就開始不提倡使用 mysql_ 開頭的介面了,現在使用 mysql_connet 通常除錯的時候會報警告說這個不該用

mysqli 使用起來其實更簡單

$url = "localhost";
$usr = "root";
$paw = "123";
$database = "mdb";

//$link = 0;
$link = mysqli_connect($url,$usr,$paw,$database) 
	or die("Error " . mysqli_error($link));
$query = "SELECT gitid,cid from carts where uid = $uid ";
$result = $link->query($query);
while($row=mysqli_fetch_array($result)){
//do you action
}

PDO其實也是不錯的選擇,mysqli自然更方便

下面講講如何在伺服器端防注入(當然用JS檢查表單也很常用)。

SQL注入很容易理解,例如獲取表單資料

$postedName = $_POST['name_input'];
$query = "INSERT INTO table_name (name) values ('$postedName')";

那麼壞人如果給你的 name_input 裡不是個正常名字而是如下這樣

jack'"; Drop table table_name; "'-
如果這時候還直接傻乎乎地 query 那就麻煩了。

PHP這個放注入的思路其實就是限制了query語句的自由度:引數就是引數,不要想加個分號變成一個命令。

這樣做:

$stmt = $mysqli->prepare("INSERT INTO table_name (name) VALUES (?)");
$stmt->bind_param('s', $postedName);

//只要確保引數在下一步 execute 之前賦值就行了
$stmt->execute();
很簡單, 在 prepare 函式裡面把引數用 ‘?’ 來替代,然後使用 bind_param 繫結引數。在 bind_param 中,第一個引數 's' 代表了引數的型別與個數(此處為一個字串型別)。如官方的例子
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);
就是綁定了四個引數,三個為字串,一個為數字。非常簡便。

這樣一來就不用怕一個引數被惡意擴充套件為一個語句來搗亂了。