$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
<span style="font-size:14px;" data-filtered="filtered"></span>
這種情況下,PHP只是簡單的將sql語句傳送給mysql server,##這與我們平時使用mysql_real_escape_string將字串進行轉義,再拼接成SQL語句沒有差別(只是由PDO本地驅動完成轉義的),顯然這種情況下還是有可能造成SQL注入的,也就是說在php本地調用pdo prepare中的mysql_real_escape_string來操作query,使用的是本地單字節字元集,而我們傳遞多位元組編碼的變數時,有可能還是會造成SQL注入漏洞(php 5.3.6先前版本的問題之一,這也就解釋了為何在使用PDO時,建議升級到php 5.3.6 ,並在DSN字串中指定charset的原因。給mysql Server指定字元集,並將變數傳送給MySQL Server完成根據字元轉義。本地轉義而交由MySQL Server轉義呢? 。 #這次PHP是將SQL模板和變數是分兩次傳送給MySQL的,由MySQL完成變數的轉義處理,既然變數和SQL模板是分兩次發送的,那就不存在SQL注入的問題了,但需要在DSN中指定charset屬性,如:
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root');
#那麼,有個問題,如果在DSN中指定了charset, 是否還需要執行set names
A. 告訴mysql server, 用戶端(PHP程式)提交給它的編碼是什麼
B. 告訴mysql server, 用戶端需要的結果的編碼是什麼
也就是說,如果資料表使用gbk字元集,而PHP程式使用UTF-8編碼,我們在執行查詢前運行set names utf8, 告訴mysql server正確編碼即可,無須在程式中編碼轉換。這樣我們以utf-8編碼提交查詢到mysql server, 得到的結果也會是utf-8編碼。省卻了程式中的轉換編碼問題,不要有疑問,這樣做不會產生亂碼。
那麼在DSN中指定charset的作用是什麼? 只是告訴PDO, 本地驅動轉義時使用指定的字元集(並不是設定mysql server通訊字元集),設定mysql server通訊字元集,還得使用set names
相關推薦:
以上是PDO方式連接mysql可以防注入的原因的詳細內容。更多資訊請關注PHP中文網其他相關文章!