一、幾個與特殊字符處理有關的PHP函數
函數名 | 釋義 | 介紹 |
htmlspecialchars | 將與、單雙引號、大於和小於號化成HTML格式 | &轉成& "轉成" ' 轉成' <轉成< >轉成> |
htmlentities() | 所有字符都轉成HTML格式 | 除上面htmlspecialchars字符外,還包括雙字節字符顯示成編碼等。 |
addslashes | 單雙引號、反斜線及NULL加上反斜線轉義 | 被改的字符包括單引號 (')、雙引號 (")、反斜線 backslash (\) 以及空字符NULL。 |
stripslashes | 去掉反斜線字符 | 去掉字符串中的反斜線字符。若是連續二個反斜線,則去掉一個,留下一個。若只有一個反斜線,就直接去掉。 |
quotemeta | 加入引用符號 | 將字符串中含有 . \\ + * ? [ ^ ] ( $ ) 等字符的前面加入反斜線 "\" 符號。 |
nl2br() | 將換行字符轉成<br> | |
strip_tags | 去掉HTML及PHP標記 | 去掉字符串中任何 HTML標記和PHP標記,包括標記封堵之間的內容。注意如果字符串HTML及PHP標籤存在錯誤,也會返回錯誤。 |
mysql_real_escape_string | 轉義SQL字符串中的特殊字符 | 轉義 \x00 \n \r 空格 \ ' " \x1a,針對多字節字符處理很有效。mysql_real_escape_string會判斷字符集,mysql_escape_string則不用考慮。 |
下面針對常用表單特殊字符處理進行總結:
測試字符串:
$dbstr='D:\test <a href="http://www.metsky.com">http://www.metsky.com</a>,天緣博客 \'!=\'1\' OR \'1\' </DIV> <script language="javascript" type="text/javascript">alert("Fail");</script> <?php echo "<br/>PHP OUTPUT"; ?>';
測試代碼:
header("Content-Type: text/html; charset=UTF-8"); echo "------------------------------------------------------<br/>\r\n"; echo $dbstr."<br/>\r\n------------------------------------------------------<br/>\r\n"; $str=fnAddSlashes($_POST['dd']); echo $str."<br/>\r\n------------------------------------------------------<br/>\r\n"; $str = preg_replace("/\s(?=\s)/","\\1",$str);//多個連續空格只保留一個 $str = str_replace("\r","<br/>",$str); $str = str_replace("\n","<br/>",$str); $str = preg_replace("/((<br\/?>)+)/i", "<br/>", $str);//多個連續<br/>標籤只保留一個 $str=stripslashes($str); echo strip_tags($str)."<br/>\r\n------------------------------------------------------<br/>\r\n"; echo htmlspecialchars($str)."<br/>\r\n------------------------------------------------------<br/>\r\n"; echo htmlentities($str)."<br/>\r\n------------------------------------------------------<br/>\r\n"; echo mysql_escape_string($str)."<br/>\r\n------------------------------------------------------<br/>\r\n";
字符串包含:反斜槓路徑,單雙引號,HTML標記、鏈接、未封堵的HTML標記,數據庫語法容錯,JS執行判斷,PHP執行判斷,多個連續回車換行符和空格。其中有些概念有包含關係,下同。
源碼輸出如下(會執行JS腳本):
二、表單提交數據處理
1、強制加入反斜線
由於有些主機默認開啓魔術引用get_magic_quotes_gpc,有些可能關閉,所以在程序上最好一律強制加入反斜線,這樣可以統一處理,字符涉及單引號、雙引號和反斜線。
function fnAddSlashes($data) { if(!get_magic_quotes_gpc()) //只對POST/GET/cookie過來的數據增加轉義 return is_array($data)?array_map('addslashes',$data):addslashes($data); else return $data; }
使用函數fnAddSlashes($data);結果如下圖(不會執行JS腳本,但HTML、JS和PHP標記仍需容錯處理):
使用stripslashes、換行替換、空格替換後結果如下圖:
2、對特殊字符處理
以下是幾個常用字符串處理,可以視具體情況取捨。由於上面已經對提交表單數據進行一次轉義,所以如果需要對內容替換或過濾需要考慮addslashes對相關字符的影響,替換或查找時需考慮反斜槓的添加。其它字符替換不影響,比如\r\n替換。
A、多個連續空格只保留一個
$data = preg_replace("/\s(?=\s)/","\\1",$data );//多個連續空格只保留一個
B、回車換行替換成<br/>
$data = str_replace("\r","<br/>",$data );
$data = str_replace("\n","<br/>",$data );
//html中默認<br>沒封堵,xhtml中<br/>有封堵,建議使用<br/>,更多區別:http://stackoverflow.com/questions/1946426/html-5-is-it-br-br-or-br
C、多個連續<br/>只保留一個
$data = preg_replace("/((<br\/?>)+)/i", "<br/>", $data );//多個連續<br/>標籤只保留一個
D、全部過濾HTML標記
該方式是全部過濾潛在危險的標記,包括HTML、鏈接、未封堵HTML標記、JS、PHP。
使用函數strip_tags($data)
該函數使用後會過濾全部的HTML標記(包括鏈接)和PHP標記、JS代碼等,其中鏈接會保留鏈接原文只是去除<a>標記和href部分內容,PHP標記和JS標記則會整體去除,包括中間的內容,如下圖:
E、不過濾標記,只是把他們HTML化
該方法是把原提交內容全部按照普通文本來處理。
使用函數htmlspecialchars($data),該函數執行後會把提交數據全部按照普通文本來展示,如下圖:
使用htmlentities函數執行結果(中文顯示亂碼):
三、寫入數據庫
由於使用addslashes($data)後對於高級的可信任用戶可以直接寫入數據庫,但是addslashes無法攔截使用0xbf27代替的單引號,所以最好還是使用mysql_real_escape_string或mysql_escape_string進行轉義,不過轉義之前需先去除反斜槓(假設已默認開啓addslashes)。
function fnEscapeStr($data) { if (get_magic_quotes_gpc()) { $data= stripslashes($value); } $data="'". mysql_escape_string($value) ."'"; return $data; } $data=fnEscapeStr($data);
執行後如下圖:
四、提交後的即時顯示
1、如果上文使用了addslashes,則必須在把數據回顯之前去除反斜線
使用函數stripslashes($data)
注意這個函 數只是面向被addslashes($data)處理後的數據,要謹慎使用,否則會導致反斜線丟失(比如內容的文件夾路徑分割線、驅動器路徑等),天緣前幾天出現的錯誤就是因爲在數據庫讀取時使用了這個函數(代碼是老代碼,忘記修改了)導致再次寫入數據庫導致很多路徑中的反斜槓丟失,要不也沒有本文了。
2、使用函數htmlspecialchars($data),該函數執行後會把提交數據全部按照文本來展示,除非允許鏈接等需特殊處理外,可以一律使用 htmlspecialchars輸出,尤其是對於未封堵的HTML標記,如果既沒有過濾再不採用標記轉換,那麼輸出後可能會導致版面混亂。
htmlentities則不建議使用,一方面對輸出的源碼造成很大的閱讀障礙,再者使用htmlentities函數會造成雙字節字符比如中文會顯示一堆亂碼。其它字符顯示還算正常。
轉載自 天緣博客 http://www.metsky.com/archives/377.html