對於Web開發,真的是我的處女地啊,什麼也不懂,不會,完全的空白。大學學習時,寫過JSP,也寫過幾行HTML,也還算知道表單這個東西。
表單可以用來收集用戶的輸入信息,將輸入信息傳遞到服務器,服務器對用戶的這些信息進行處理。服務器對這些數據如何處理,使用哪個腳本文件進行處理呢?下面就通過一個簡單的HTML表單程序來說明這些問題。
比如有以下HTML代碼:
<html>
<body>
<form action="register.php" method="post">
Name:<input type="text" name="name" />
E-Mail:<input type="text" name="email" />
<input type="submit" />
</form>
</body></html>
然後又有對應的register.php
文件如下:
<html>
<body>
Welcome
<?php
if (isset($_POST["name"]))
{
echo $_POST["name"];
}
?> <br />
Your email address is:
<?php
if (isset($_POST["email"]))
{
echo $_POST["email"];
}
?><br />
</body></html>
現在再來說說上面的代碼,顯示使用HTML定義了表單,並指定了以post的方式提交該表單到服務器,同時還指定了服務器使用register.php
腳本文件來出來該表單提交的內容。
在register.php
腳本文件中,對用戶提交的處理進行簡單的獲取與輸出,使用了超全局變量$_POST
。提交表單的方式有GET和POST兩種方式,這兩種方式都創建數組(例如,array(key => value, key2 => value2, key3 => value3, …))。該數組包含鍵/值對,其中的鍵是表單控件的名稱,而值是來自用戶的輸入數據。GET和POST操作提交的數據分別被對應到PHP中的超全局變量$_GET
數組和$_POST
數組中。它們是超全局變量,這意味著對它們的訪問無需考慮作用域,不需要任何特殊代碼,我們就能夠從任何函數、類或文件訪問它們。
$_GET
是通過URL參數傳遞到當前腳本的變量數組;而$_POST
是通過HTTP POST傳遞到當前腳本的變量數組。關於HTTP中GET和POST,這又是一堆復雜的的東西,在我的另一篇博文《詳解HTTP中GET和POST的區別》中,我進行了詳細的分析與描述。
可以看到,在register.php
中,我只是對用戶提交的數據進行了簡單的輸出,而並沒有進行復雜的處理,比如用戶提交的用戶名符不符合規范啊?用戶輸入的郵件格式是否正確啊?等等問題,這就涉及到驗證表單的問題。
其實很多時候,我們在注冊一個網站的會員的時候,輸入了不合法的E-Mail地址以後,都會立刻有一個提示標記,而這些都是在客戶端使用了JS進行了一篇簡單的校驗。對於我們來說,客戶端的任何校驗都是不可信的校驗,在客戶端校驗,只是減少了用戶出錯的可能;對於提交到服務器的數據,我們必須要進行二次校驗,這樣才能放心的對數據進行處理。
對於有一些“調皮的用戶”,就喜歡尋找你代碼的bug,給你來一個SQL注入啊,或者跨站點腳本攻擊什麼的。遇到這些,就有些麻煩了,如果有這些麻煩,說明你的代碼有問題,你需要去解決這些問題。
對於這些防范工作,你可能覺的很難去做到,但是對於PHP來說,它都想到了(PHP就是功能多,就是這麼倔強)。在處理用戶的提交數據時,只需要將用戶輸入的數據在以下的4個函數中走一遍,就可以防范那些簡單的,邪惡的攻擊了。這4個標准函數如下:
對於escapeshellarg
和escapeshellcmd
,實際用的比較少,這不做總結,請自行查閱文檔。而htmlentities
和strip_tags
基本上是必用的,比如現在基於上面的代碼進行測試:
在name輸入欄中輸入:<b>http://www.jellythink.com</b>
,我們期望能輸出<b>http://www.jellythink.com</b>
,而實際上只是輸出了粗體的http://www.jellythink.com了。很明顯這不是我們所期望的。很有可能,有的用戶故意輸入一些代碼,在你的網頁上搗亂,怎麼辦?這個時候,我們可以使用htmlentities
函數對用戶提交數據中含有的一些在HTML中有特殊含義的字符轉換為浏覽器可以表現的字符串,而不是當做HTML來被浏覽器所解釋。好了,我們將PHP代碼修改為以下這樣,就不會有問題了:
<?php
if (isset($_POST["name"]))
{
echo htmlentities($_POST["name"]);
}?> <br />
當然了,我們也可以使用strip_tags
函數來剔除用戶提交數據中的所有HTML標簽了,具體請自行測試。
在實際項目中,得到用戶提交的數據以後,我們處理的步驟一般如下:
上面說了那麼多了,都是安全防范方面的,比如現在要求用戶輸入一個E-Mail地址,用戶沒有輸入SQL注入啊,跨站點腳本什麼的。那麼我在服務器端又如何判斷用戶輸入的內容到底符不符合一個郵箱的規則呢?
上面說到如何判斷用戶輸入的內容到底符不符合郵箱規則呢。很多時候,我們去判斷用戶輸入的內容是否符合一定的規則,都是使用的正則匹配去確定的,先不說正則匹配書寫起來有多麻煩,就是寫對了,滿足所有條件都難。還好,萬能的PHP支持各種擴展,我們可以使用PHP的Filter擴展來完成一些已經定義好的校驗。比如以下代碼:
<?php
if (isset($_POST["email"]))
{
$email = $_POST["email"];
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo "Invalidate E-Mail";
}
}
?>
我們可以就這樣簡單的完成對郵箱格式的驗證,再也不用去寫那些麻煩的正則表達式了。
上面只是對Filter的一個簡單的例子,而Filter的功能遠不止於此,比如完成URL的驗證等等,其余的功能,就等你去發現和實踐了。
我們都知道,在HTML中,是存在多選的,比如以下HTML代碼:
<html><body>
<form action="register.php" method="post">
Language:
<select name="languages[]" multiple="multiple">
<option value="CSharp">C#</option>
<option value="JavaScript">JavaScript</option>
<option value="Cpp">C++</option>
<option value="PHP">PHP</option>
</select>
<input type="submit" />
</form></body></html>
那麼PHP是如何接收處理呢?PHP是這樣干的:
<?php
if (isset($_POST["languages"]))
{
foreach ($_POST["languages"] as $key => $value)
{
$language = htmlentities($value);
echo "$key => $language<br/>";
}
}?>
好了,關於PHP處理HTML表單的問題,我想應該總結清楚了,使用PHP處理表單的時候,更多的時候,是需要注意安全方面的問題。寥寥幾百字,總結的夠了。