當然addslashes也不是毫無用處,它是用於單位元組字串的處理,多位元組字元還是用mysql_real_escape_string吧。
開啟magic_quotes_gpc來防止SQL注入
php.ini中有一個設定:magic_quotes_gpc = Off
這個預設是關閉的,如果它開啟後將自動把使用者提交對sql的查詢進行轉換,
比如把 ' 轉為 '等,對於防止sql注射有重大作用。
如果magic_quotes_gpc=Off,則使用addslashes()函數
另外對於php手冊中get_magic_quotes_gpc的舉例:
代碼如下 |
複製代碼 |
if (!get_magic_quotes_gpc()) { $lastname = addslashes($_POST[‘lastname’]); } else { $lastname = $_POST[‘lastname’]; } |
最好對magic_quotes_gpc已經開放的情況下,還是對$_POST[’lastname’]進行檢查一下。
再說下mysql_real_escape_string和mysql_escape_string這2個函數的區別:
mysql_real_escape_string 必須在(PHP 4 >= 4.3.0, PHP 5)的情況下才能使用。否則只能用 mysql_escape_string ,兩者的區別是:mysql_real_escape_string 考慮到串連的當前字元集,而mysql_escape_string 不考慮。
(1)mysql_real_escape_string -- 轉義 SQL 陳述式中使用的字串中的特殊字元,並考慮到串連的當前字元集
使用方法如下:
代碼如下 |
複製代碼 |
$sql = "select count(*) as ctr from users where username02.='".mysql_real_escape_string($username)."' and 03.password='". mysql_real_escape_string($pw)."' limit 1"; |
自定函數
代碼如下 |
複製代碼 |
function inject_check($sql_str) { return eregi('select|insert|and|or|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str); } function verify_id($id=null) { if(!$id) { exit('沒有提交參數!'); } elseif(inject_check($id)) { exit('提交的參數非法!'); } elseif(!is_numeric($id)) { exit('提交的參數非法!'); } $id = intval($id); return $id; } function str_check( $str ) { if(!get_magic_quotes_gpc()) { $str = addslashes($str); // 進行過濾 } $str = str_replace("_", "_", $str); $str = str_replace("%", "%", $str); return $str; } function post_check($post) { if(!get_magic_quotes_gpc()) { $post = addslashes($post); } $post = str_replace("_", "_", $post); $post = str_replace("%", "%", $post); $post = nl2br($post); $post = htmlspecialchars($post); return $post; }
|
總結一下:
* addslashes() 是強行加;
* mysql_real_escape_string() 會判斷字元集,但是對PHP版本有要求;
* mysql_escape_string不考慮串連的當前字元集。
dz中的防止sql注入就是用addslashes這個函數,同時在dthmlspecialchars這個函數中有進行一些替換$string = preg_replace(/&((#(d{3,5}|x[a-fA-F0-9]{4}));)/, &1,這個替換解決了注入的問題,同時也解決了中文亂碼的一些問題。