2011-08-31 111 views
-2
<?php 
$g_id=$_GET['gid']; 

// $one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id); 
// $result = $one->fetch(); 
?> 

Rename groupname: <input type="text" placeholder="<?php // $one['gr_name']; ?>"> 

這是我的小代碼,根本不工作,我找不到我做錯了什麼。任何幫助,將不勝感激。php SQL PDO-> Fetch()問題

+2

你爲什麼不使用預處理語句?沒有它們,這個腳本就很脆弱。 http://php.net/manual/en/pdo.prepared-statements.php –

+1

這可能是一個錯字,但仍然是:使用'$ result ['gr_name']'而不是'$ one ['gr_name']' –

+0

你看到什麼錯誤信息? – TJHeuvel

回答

2

結果存儲在$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甚至不用擔心評估綁定到預準備語句的任何內容。

  1. PDO稱到MySQL,"The data for :id is ' OR 1=1 --"
  2. MySQL的地方找到的位置:ID是在準備好的聲明。 (在這個例子中,字符28)
  3. MySQL的統計數據的長度(在這種情況下,11個字符)
  4. MySQL不會把一年級的數學和記憶,它應該把一切從字符28 39字符。
  5. 的MySQL插入數據,現在查詢看起來是這樣的:

    DELETE FROM users WHERE id=' OR 1=1 --

  6. 然而,因爲它知道數據的位置,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中重要的任何字符(即<>),並將它們轉換爲它們的文字值(&lt;&gt;)。

&lt;script type=&quot;text/javascript&quot;&gt; 
alert('You just been H4X0RED!!!!1 LOLS'); 
&lt;/script&gt; 

在每個人的瀏覽器的HTML解析器解釋&lt不是作爲HTML標籤的開始,但作爲一個標誌,以實際輸出的字符<。這基本上就是數據庫引擎對輸入到預處理語句中的所有數據的處理。除了在SQL字母組成有效的命令(以及有效的數據)之外,引擎將數據中的所有字符解釋爲它們的字面值。所以不是:

DELETE FROM users WHERE id = 0 OR 1=1 --' 

它評估數據中的每個字符,因爲它的字面值。在HTML中,這將是:

DELETE FROM users WHERE id = &#48;&#32;&#79;&#82;&#32;&#49;&#61;&#49;&#32;&#45;&#45;&#39; 

如果你看一下both here,他們都輸出同樣的事情,除了在第二,該「數據」被理解爲它是由解析器文本值,而不是它的功能價值。 SQL做同樣的事情。通過使用數據的字面值,實際數據中的任何一個都不能被解釋爲命令或其中的一部分。

+0

感謝您的幫助!特別是準備好的陳述位。我仍然在努力瞭解如何保護查詢,但這只是我(即使我已經閱讀了鏈接)。你介意我是否要求你提供一些解釋? –

+1

@Andras Sebestyen我盡力解釋它。合理? –

+0

我也在爲此苦苦掙扎。如果我的查詢看起來像''SELECT * FROM contactgroups ORDER BY $ sortfield「'? –

4
  • 你的PHP代碼被註釋掉
  • 你不是叫echo
  • 您使用$one代替$result
  • 你不消毒的投入,這是不是造成這個問題,但它是應該解決的問題。消毒是$g_id = intval($_GET['gid']);容易,但我建議尋找到prepared statements

說了這麼多,這應該工作:

<?php 
$g_id=$_GET['gid']; 

$one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id); 
$result = $one->fetch(); 
?> 

Rename groupname: <input type="text" placeholder="<?php echo $result['gr_name']; ?>">