結果存儲在$result
數組中,而不是PDO對象$one
。如果你不打算使用短標籤,這也需要回顯。
<input type="text" placeholder="<?php echo $result['gr_name']; ?>">
我會用shorttags,所以如果你的PHP安裝程序已啓用它們,但它們在PHP 5.6被棄用:
<input type="text" placeholder="<?= $result['gr_name']; ?>">
可以使用shorttags現在,我將繼續用它們來抗議刪除這個令人難以置信的有用功能。貶低短標籤會打破很多WP主題和簡單的模板引擎!
你也應該考慮使用prepared statements。沒有它們,這個腳本就容易受到SQL注入的影響。
<?php
$query = $pdo->prepare("SELECT * FROM contactgroups WHERE id=:id");
if($query->execute(array(':id' => $_GET['id']))) {
$result = $query->fetch();
?>
<input type="text" placeholder="<?php echo $result['gr_name']; ?>" />
<?php } ?>
PDO如何防止SQL注入(太長,加入了註釋 - 向下滾動看到一個更好的解釋)
讓我們從一個查詢開始:
mysql_query("DELETE FROM users WHERE id='".$id."'");
如果$id = "' OR 1=1 --";
則當發送到MySQL時,查詢將看起來像這樣( - 表示開始評論):
DELETE FROM users WHERE id='' OR 1=1 --'
顯然,這將遵循可能是災難性的,可能是不可逆的(除非你有一些聰明的DB管理員)的破壞。這裏的修復,而不是使用冗長,mysql_real_escape_string()
(我真的不理解爲什麼函數名是擺在首位這麼羅嗦),我們現在可以使用PDO預處理語句。
通過PDO::preparing()
聲明要發送消息到你的數據庫,告訴它來存儲和優化這個查詢,因爲這將在以後使用。您的數據庫存儲優化查詢,並仔細記錄數據所屬的位置。
$statement = $pdo->prepare('DELETE FROM users WHERE id=:id');
PDO會給你的PDOStatement,你可以PDO::bindParam()
值和執行的實例。所以讓我們來做並執行。
$statement->bindParam(':id', $id);
$statement->execute();
現在一些幕後魔法發生在這裏。 PDO將數據發送到MySQL。 MySQL檢查數據並將其插入到準備好的語句中。通過知道數據應該放在何處以及插入數據的時間長短,MySQL可以確定查詢中不需要執行的字符範圍(讀取:數據)。 因此,當黑客嘗試SQL注入時,MySQL甚至不用擔心評估綁定到預準備語句的任何內容。
- PDO稱到MySQL,
"The data for :id is ' OR 1=1 --"
- MySQL的地方找到的位置:ID是在準備好的聲明。 (在這個例子中,字符28)
- MySQL的統計數據的長度(在這種情況下,11個字符)
- MySQL不會把一年級的數學和記憶,它應該把一切從字符28 39字符。
的MySQL插入數據,現在查詢看起來是這樣的:
DELETE FROM users WHERE id=' OR 1=1 --
然而,因爲它知道數據的位置,MySQL只分析了管道以外的一切(|)的命令和關鍵字。
DELETE FROM users WHERE id=|' OR 1=1 --|
所以管之間的文本實際上從未得到分析。當MySQL需要比較id時,它仍然將表中的id與數據進行比較,但由於數據從未執行過,所以SQL注入失敗。
一個更好的PDO如何防止SQL注入
當我們準備與PDO一份聲明中解釋,它會通知即將到來的查詢的數據庫,其中的數據將在查詢中。當我們將數據綁定到該查詢並執行它時,數據庫會在幕後進行一些工作,以確保SQL注入受到阻礙。
讓我們把這個幕後工作帶到另一個環境。您可以管理一個您自己編寫完整引擎的PHP博客。你是你寫的,直到一些挺舉決定發佈此評論的聰明評論系統而自豪:你在電腦屏幕大叫一些四個字母的話後,並確保該腳本小子的父母從來沒有讓他在
<script type="text/javascript">
alert('You just been H4X0RED!!!!1 LOLS');
</script>
再次使用互聯網,您可以通過htmlspecialchars()
解決代碼中的XSS漏洞。
$comment_text = htmlspecialchars($_POST['comment_text']);
現在你在這裏做了什麼?當腳本小孩在凌晨3點醒來,潛入他的電腦再次嘗試代碼時,htmlspecialchars()
將他蹩腳的幽默嘗試變成了亂七八糟的混亂。該函數採用HTML中重要的任何字符(即<
和>
),並將它們轉換爲它們的文字值(<
和>
)。
<script type="text/javascript">
alert('You just been H4X0RED!!!!1 LOLS');
</script>
在每個人的瀏覽器的HTML解析器解釋<
不是作爲HTML標籤的開始,但作爲一個標誌,以實際輸出的字符<
。這基本上就是數據庫引擎對輸入到預處理語句中的所有數據的處理。除了在SQL字母組成有效的命令(以及有效的數據)之外,引擎將數據中的所有字符解釋爲它們的字面值。所以不是:
DELETE FROM users WHERE id = 0 OR 1=1 --'
它評估數據中的每個字符,因爲它的字面值。在HTML中,這將是:
DELETE FROM users WHERE id = 0 OR 1=1 --'
如果你看一下both here,他們都輸出同樣的事情,除了在第二,該「數據」被理解爲它是由解析器文本值,而不是它的功能價值。 SQL做同樣的事情。通過使用數據的字面值,實際數據中的任何一個都不能被解釋爲命令或其中的一部分。
你爲什麼不使用預處理語句?沒有它們,這個腳本就很脆弱。 http://php.net/manual/en/pdo.prepared-statements.php –
這可能是一個錯字,但仍然是:使用'$ result ['gr_name']'而不是'$ one ['gr_name']' –
你看到什麼錯誤信息? – TJHeuvel