2012-10-23 29 views
2

我一直在做一個PHP網站,在我的本地機器上開發。真的很新,所以這是我嘗試過的第一件事。當我搬到我的主人,我得到以下錯誤:何時使用PDO準備的查詢。 mysql_real_escape錯誤

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied    for user 'matthew'@'localhost' (using password: NO) on line 11 

我已經搜查放在這裏公平一點,我敢肯定它,因爲我需要「準備」我的查詢。我不確定什麼時候準備什麼時候準備,什麼時候不準備。我加了一些我下面的查詢的詳細講解:

連接到數據庫:

$hostname = "localhost"; 
$username = "root"; 
$password = "root"; 

try { 
    $dbh = new PDO("mysql:host=$hostname;dbname=wmpt", $username, $password); 
//echo "Connected to database"; // check for connection 
    } 
catch(PDOException $e) 
    { 
    echo $e->getMessage(); 
    } 

下面是一個例子查詢:

$username = mysql_real_escape_string($_POST['run']); 


$STH = $dbh->query("SELECT * FROM tblusers WHERE username = '$username' "); 
$STH->setFetchMode(PDO::FETCH_ASSOC); 
$result = $STH->fetch(); 

我的問題是,我只需要如果我用用戶提交的數據查詢/插入/更新數據庫,「準備」查詢?

上述查詢是否爲不良做法?即我想如果它沒有包含用戶提交的數據查詢

$STH = $dbh->query("SELECT * FROM tblusers WHERE username LIKE '%hotmail%' "); 

這也許一個壞榜樣,但我說明開發商定義的查詢。

這是我得到的原因,以及我如何避免:

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for  user 'matthew'@'localhost' (using password: NO) on line 11 

回答

4

爲了解決您遇到的錯誤,mysql_real_escape_string()需要通過mysql_connect()一個打開的連接。因爲你沒有,所以它試圖連接和失敗(使用用戶名matthew,而你的PDO連接root)。此外,你不能(或,不應該)混合和匹配mysql_real_escape_string()PDO - 他們是不同的庫。

關於「何時」使用準備好的語句,一般的經驗法則是每當值沒有硬編碼時。 LIKE '%hotmail%'的示例不需要準備,它是硬編碼的,並且永遠不會改變(除非您手動更新它,當然)。

如果您有一個查詢會接受任何類型的變量,那麼可以使用$_POST$_GET或開發人員在查詢前提出10行的變量的數據,您應該使用準備好的語句(或在至少逃脫它,檢查出PDO::quote)。

+1

可以肯定,您應該將所有*和*所有*值都轉義成您的查詢。即使程序員定義的值也可能有意想不到的問題。 – tadman

+0

@tadman準確地說;任何沒有硬編碼的變量都應該被轉義 - 無論是通過一個準備好的語句還是至少一個轉義函數。 – newfurniturey

+0

感謝有關最佳實踐的細節 - 真的很有幫助 – matt

4

如果您使用的是PDO,則不應使用mysql_real_escape_string。 PDO庫有一個非常強大的SQL placeholder method,做得更好。

$STH = $dbh->query("SELECT * FROM tblusers WHERE username = :username"); 
$STH->bindParam(':username', $username); 
$STH->setFetchMode(PDO::FETCH_ASSOC); 
$result = $STH->fetch(); 
+0

謝謝加載,列表也非常感謝 - 偉大的指南 – matt