2014-11-22 49 views
-2

我試圖轉義一個字符串,我將其放入一個語句。PDO mysql_real_escape_string如何在準備好的陳述中使用

我知道PDO準備並執行(對於那些不知道PDO的人準備一個語句來停止任何額外的命令被運行,所以語句知道在注入變量數據之前它正在運行什麼,從而消除了被注入)我現在的麻煩是我想用MySQL規則之外的變量來運行一個語句(見下文)。

$sql = $this->PDO->prepare("SELECT * FROM `weight` WHERE `user_id`=:id ORDER BY $order $direction"); 

正如你可以看到我使用自定義的順序由和ASC/DESC上述作品statment,但我不覺得這是足夠安全的。把方向作爲一個switch語句很容易,但爲了將來的擴展,我想逃避$ order而不是使用開關或硬編碼數組。

我在$ order中使用了許多方法的mysql_real_escape_string,但聲明不喜歡它,有什麼想法嗎?編輯----功能下面,沒有猜測工作真正需要的全部代碼..

public function getWeightByUserOrderBy($id, $order, $direction) { 
$order1 = $PDO->quote($order); 
    $sql = $this->PDO->prepare("SELECT * FROM `weight` WHERE `user_id`=:id ORDER BY $order1 $direction"); 
    $sql->execute(array(
     ":id" => $id 
    )); 
    $sql = $sql->fetchall(); 
    return $sql; 
} 
+1

*「我在$ order中使用了許多方法的mysql_real_escape_string,但是語句不喜歡它」* - **答案:**這是因爲當您混用API時,MyQL不喜歡它。僅使用一種API類型。顯示完整的代碼並閱讀[** PDO與準備語句**](http://php.net/pdo.prepared-statements)是如何工作的。 – 2014-11-22 23:05:24

+2

如果您完全控制了查詢內容,則沒有注入的範圍。 '$ order'和'$ direction'的內容應該針對白名單進行驗證,並且只使用_your_值。您根本不需要使用'real_escape_string()',特別是使用不同的&棄用的API。 – 2014-11-22 23:13:10

+1

要添加到@ MikeW的評論,您不能使用'mysql_real_escape_string'而不使用'$ order'並且不使用PDO特定的轉義函數。轉義函數僅適用於值而不適用於列名。因此,如果'$ order'的值是用戶提供的,那麼您總是需要一個硬編碼數組(白名單)來檢查。該數組可以填充查詢數據庫的列名當然... – jeroen 2014-11-22 23:30:38

回答

0

你不會想用mysql_real_escape_string,從一個過時的接口。

對於$direction,請驗證它是否包含DESCDESCENDING。否則,將其設置爲空字符串或ASC

如果$order應該包含標識符(列名),那麼您可以使用反引號將其轉義,並刪除變量中的任何反引號。如果$order包含表達式,那有點棘手。

+1

*「您不希望使用來自已棄用接口的'mysql_real_escape_string'」。 * - OP使用PDO(最少發佈1行代碼);它真的歸結爲這兩個API不混合,正如我在OP的問題下的評論中所說的那樣。 OP應該發佈完整的代碼以避免所有的猜測。 – 2014-11-22 23:17:02