MySQL pdo預處理能防止sql注入的原因:
1、先看預處理的語法
$pdo->prepare('select * from biao1 where id=:id');
$pdo->execute([':id'=>4]);
2、語句一,服務器發送一條sql給mysql服務器,mysql服務器會解析這條sql。
語句二,服務器發送一條sql給mysql服務器,mysql服務器不會解析這條sql,只會把execute的參數當做純參數賦值給語句一。哪怕參數中有sql命令也不會被執行,從而實現防治sql注入。
見圖:
普通的sql,直接一條sql語句執行,web服務器自己拼湊sql的時候有可能會把危險的sql語句拼湊進去。
PDO的sql,讓mysql服務器自己拼湊,就算有危險的語句,也只會當做參數處理,不會執行。
注意:為了讓mysql服務器去拼湊sql,而不是web server去拼湊,必須在創建pdo對象的時候加個參數:
這個參數叫模擬prepare,默認是TRUE,意思是讓web server代替mysql去做prepare,達到模擬prepare的作用。(web server實現模擬prepare的原理其實也就是底層用系統函數自行拼湊sql,和手動拼湊沒區別,所以還是會把危險的sql拼湊進去,然后給mysql服務器執行,依然會被sql注入)
所以必須設置為FALSE。
$this->_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
PDO::ATTR_EMULATE_PREPARES
參數為TRUE時,就算調用prepare,execute等pdo函數,底層依舊和普通的mysql沒區別,直接發送一條webserver拼湊好的sql語句給mysql server。如圖:
PDO::ATTR_EMULATE_PREPARES
設置為FALSE后,就會真的執行prepare,execute,如圖: