Friday, November 9, 2012

[PHP] 淺談字元自動跳脫 (magic_quotes_gpc的設定) (addslashes、stripslashes的使用時機)

我們做了一個表單欄位,讓使用者可以輸入文字後寫入資料庫,假設使用者輸入的文字為Tom's book,而且主機的php.ini中magic_quotes_gpc設定為Off,則會寫入資料庫會發生錯誤,那是因為文字中帶了一個單引號( ' )。

舊版的php安裝後,magic_quotes_gpc會預設On,所以當使用者輸入Tom's book送出後,接收頁在用$_POST或$_GET接值時,系統會自動加上跳脫字元( \ )反斜線,讓文字變成Tom\'s book,所以在寫入資料庫時,並不會發生錯誤,而且去查看sql的欄位值也是正確的Tom's book。

PHP從5.4.X開始,magic_quotes_gpc的預設值改成Off,也就是希望程式撰寫人員應該自己去處理特殊字元的問題。

所以,了解跳脫相關函式與應用方法,是必要的...

我們可以利用get_magic_quotes_gpc()去判斷系統的magic_quotes_gpc值為何,再決定是否手動跳脫,否則系統已經跳脫過一次了,我們又手動跳脫,就會出現重複的反斜線。
if(!get_magic_quotes_gpc()){
  //手動跳脫
}

假設系統的magic_quotes_gpc為Off,則手動跳脫程序為:
$str = $_POST['str'];  //這邊就是Tom's book
$str = addslashes($str);  //這邊就會變成Tom\'s book
然後就可以安心的進行sql的insert動作。

也有一種情形是,系統的magic_quotes_gpc為On,而我們不希望$_POST的值,會自動跳脫,則清除跳脫字元的方式為:

$str = $_POST['str'];  //這邊就是Tom\'s book
$str = stripslashes($str);  //這邊就會變成Tom's book

備註1:
有些文章會利用mysql_real_escape_string來取代addslashes,這兩個函式很相似,參考addslashes与mysql_real_escape_string的区别,故使用addslashes就好。

備註2:
讀取資料時,如果文字包含雙引號,而前端程式碼為 <input type="text" value="<?=$str?>"> 時,會因為雙引號提早閉合導致無法正確顯示,解法是加上 htmlspecialchars(),例如:  <input type="text" value="<?=htmlspecialchars($str)?>">

參考資料:
用PHP函数解决SQL injection
在PHP裡面如何做到基本的SQL injection防禦?

No comments:

Post a Comment