7 回答

TA貢獻2036條經驗 獲得超8個贊
如果您使用的是最新版本的PHP,則mysql_real_escape_string
下面列出的選項將不再可用(盡管mysqli::escape_string
它是現代版本)。這些天,該mysql_real_escape_string
選項只適用于舊版PHP上的遺留代碼。
您有兩個選項 - 轉義您的特殊字符unsafe_variable
,或使用參數化查詢。兩者都可以保護您免受SQL注入。參數化查詢被認為是更好的做法,但在使用它之前需要在PHP中更改為更新的MySQL擴展。
我們將首先覆蓋較低影響的字符串。
//Connect$unsafe_variable = $_POST["user-input"];$safe_variable = mysql_real_escape_string($unsafe_variable);mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");//Disconnect
另請參見mysql_real_escape_string
功能的詳細信息。
要使用參數化查詢,您需要使用MySQLi而不是MySQL函數。要重寫您的示例,我們需要類似以下內容。
<?php $mysqli = new mysqli("server", "username", "password", "database_name"); // TODO - Check that connection was successful. $unsafe_variable = $_POST["user-input"]; $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)"); // TODO check that $stmt creation succeeded // "s" means the database expects a string $stmt->bind_param("s", $unsafe_variable); $stmt->execute(); $stmt->close(); $mysqli->close();?>
你想要閱讀的關鍵功能就是mysqli::prepare
。
此外,正如其他人所建議的那樣,您可能會發現使用PDO之類的步驟來增加抽象層是有用的/更容易的。
請注意,您詢問的案例非常簡單,更復雜的案例可能需要更復雜的方法。特別是:
如果要根據用戶輸入更改SQL的結構,參數化查詢將無濟于事,并且不需要轉義所需的轉義
mysql_real_escape_string
。在這種情況下,您最好通過白名單傳遞用戶的輸入,以確保只允許“安全”值。如果您在條件中使用來自用戶輸入的整數并采用該
mysql_real_escape_string
方法,您將在下面的注釋中遇到Polynomial描述的問題。這種情況比較棘手,因為整數不會被引號括起來,所以你可以通過驗證用戶輸入只包含數字來處理。可能還有其他我不知道的情況。您可能會發現這是一個有用的資源,可以解決您可能遇到的一些更微妙的問題。

TA貢獻1982條經驗 獲得超2個贊
使用PDO和準備的查詢。
($conn是一個PDO對象)
$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();
添加回答
舉報