# PHP 表單驗證
")
**本節和下一節講解如何使用 PHP 來驗證表單數據。**
## PHP 表單驗證
提示:在處理 PHP 表單時請重視安全性!
這些頁面將展示如何安全地處理 PHP 表單。對 HTML 表單數據進行適當的驗證對于防范黑客和垃圾郵件很重要!
我們稍后使用的 HTML 表單包含多種輸入字段:必需和可選的文本字段、單選按鈕以及提交按鈕:
```
<h2>PHP 表單驗證實例</h2>
<p><span class="error">* 必填字段</span></p>
<form method="post" action="/demo/demo_form_validation_complete.php">
姓名:
<input type="text" name="name" value="">
<span class="error">* </span>
<br><br>
電郵:
<input type="text" name="email" value="">
<span class="error">* </span>
<br><br>
網址:
<input type="text" name="website" value="">
<span class="error"></span>
<br><br>
<label>
評論:
<textarea name="comment" rows="5" cols="40"></textarea>
<br><br>
性別:
<input type="radio" name="gender" value="female">女性
<input type="radio" name="gender" value="male">男性
<span class="error">* </span>
<br><br>
<input type="submit" name="submit" value="提交">
</form>
<h2>您的輸入:</h2>
```
上面的表單使用如下驗證規則:
| 字段 | 驗證規則 |
| --- | --- |
| Name | 必需。必須包含字母和空格。 |
| E-mail | 必需。必須包含有效的電子郵件地址(包含 @ 和 .)。 |
| Website | 可選。如果選填,則必須包含有效的 URL。 |
| Comment | 可選。多行輸入字段(文本框)。 |
| Gender | 必需。必須選擇一項。 |
首先我們看一下這個表單的純 HTML 代碼:
## 文本字段
name、email 和 website 屬于文本輸入元素,comment 字段是文本框。HTML 代碼是這樣的:
```
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
```
## 單選按鈕
gender 字段是單選按鈕,HTML 代碼是這樣的:
```
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
```
## 表單元素
表單的 HTML 代碼是這樣的:
```
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
```
當提交此表單時,通過 method="post" 發送表單數據。
### 什么是 $_SERVER["PHP_SELF"] 變量?
$_SERVER["PHP_SELF"] 是一種超全局變量,它返回當前執行腳本的文件名。
因此,$_SERVER["PHP_SELF"] 將表單數據發送到頁面本身,而不是跳轉到另一張頁面。這樣,用戶就能夠在表單頁面獲得錯誤提示信息。
### 什么是 htmlspecialchars() 函數?
htmlspecialchars() 函數把特殊字符轉換為 HTML 實體。這意味著 < 和 > 之類的 HTML 字符會被替換為 < 和 > 。這樣可防止攻擊者通過在表單中注入 HTML 或 JavaScript 代碼(跨站點腳本攻擊)對代碼進行利用。
## 關于 PHP 表單安全性的重要提示
$_SERVER["PHP_SELF"] 變量能夠被黑客利用!
如果您的頁面使用了 PHP_SELF,用戶能夠輸入下劃線然后執行跨站點腳本(XSS)。
提示:跨站點腳本(Cross-site scripting,XSS)是一種計算機安全漏洞類型,常見于 Web 應用程序。XSS 能夠使攻擊者向其他用戶瀏覽的網頁中輸入客戶端腳本。
假設我們的一張名為 "test_form.php" 的頁面中有如下表單:
```
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
```
現在,如果用戶進入的是地址欄中正常的 URL:"http://www.example.com/test_form.php",上面的代碼會轉換為:
```
<form method="post" action="test_form.php">
```
到目前,一切正常。
不過,如果用戶在地址欄中鍵入了如下 URL:
```
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
```
在這種情況下,上面的代碼會轉換為:
```
<form method="post" action="test_form.php"/><script>alert('hacked')</script>
```
這段代碼加入了一段腳本和一個提示命令。并且當此頁面加載后,就會執行 JavaScript 代碼(用戶會看到一個提示框)。這僅僅是一個關于 PHP_SELF 變量如何被利用的簡單無害案例。
您應該意識到 _<script> 標簽內能夠添加任何 JavaScript 代碼_!黑客能夠把用戶重定向到另一臺服務器上的某個文件,該文件中的惡意代碼能夠更改全局變量或將表單提交到其他地址以保存用戶數據,等等。
## 如果避免 $_SERVER["PHP_SELF"] 被利用?
通過使用 htmlspecialchars() 函數能夠避免 $_SERVER["PHP_SELF"] 被利用。
表單代碼是這樣的:
```
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
```
htmlspecialchars() 函數把特殊字符轉換為 HTML 實體。現在,如果用戶試圖利用 PHP_SELF 變量,會導致如下輸出:
```
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
```
無法利用,沒有危害!
## 通過 PHP 驗證表單數據
我們要做的第一件事是通過 PHP 的 htmlspecialchars() 函數傳遞所有變量。
在我們使用 htmlspecialchars() 函數后,如果用戶試圖在文本字段中提交以下內容:
```
<script>location.href('http://www.hacked.com')</script>
```
- 代碼不會執行,因為會被保存為轉義代碼,就像這樣:
```
<script>location.href('http://www.hacked.com')</script>
```
現在這條代碼顯示在頁面上或 e-mail 中是安全的。
在用戶提交該表單時,我們還要做兩件事:
1. (通過 PHP trim() 函數)去除用戶輸入數據中不必要的字符(多余的空格、制表符、換行)
2. (通過 PHP stripslashes() 函數)刪除用戶輸入數據中的反斜杠(\)
接下來我們創建一個檢查函數(相比一遍遍地寫代碼,這樣效率更好)。
我們把函數命名為 test_input()。
現在,我們能夠通過 test_input() 函數檢查每個 $_POST 變量,腳本是這樣的:
### 實例
```
<?php
// 定義變量并設置為空值
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
```
請注意在腳本開頭,我們檢查表單是否使用 $_SERVER["REQUEST_METHOD"] 進行提交。如果 REQUEST_METHOD 是 POST,那么表單已被提交 - 并且應該對其進行驗證。如果未提交,則跳過驗證并顯示一個空白表單。
不過,在上面的例子中,所有輸入字段都是可選的。即使用戶未輸入任何數據,腳本也能正常工作。
下一步是制作必填輸入字段,并創建需要時使用的錯誤消息。
")
- PHP 基礎
- PHP 簡介
- PHP 安裝
- PHP 語法
- PHP 變量
- PHP 5 echo 和 print 語句
- PHP 數據類型
- PHP 字符串函數
- PHP 常量
- PHP 運算符
- PHP if...else...elseif 語句
- PHP Switch 語句
- PHP while 循環
- PHP for 循環
- PHP 函數
- PHP 數組
- PHP 數組排序
- PHP 全局變量 - 超全局變量
- PHP 魔術變量
- PHP 命名空間(namespace)
- PHP 表單
- PHP 表單處理
- PHP 表單驗證
- PHP 表單驗證 - 必填字段
- PHP 表單驗證 - 驗證 E-mail 和 URL
- PHP 表單驗證 - 完成表單實例
- PHP $_GET 變量
- PHP $_POST 變量
- PHP 高級
- PHP 多維數組
- PHP 日期和時間
- PHP Include 文件
- PHP 文件處理
- PHP 文件打開/讀取/讀取
- PHP 文件創建/寫入
- PHP 文件上傳
- PHP Cookies
- PHP Sessions
- PHP 發送電子郵件
- PHP 安全的電子郵件
- PHP 錯誤處理
- PHP 異常處理
- PHP 過濾器(Filter)
- PHP JSON
- PHP 數據庫
- PHP MySQL 簡介
- PHP 連接 MySQL
- PHP MySQL 創建數據庫
- PHP 創建 MySQL 表
- PHP MySQL 插入數據
- PHP MySQL 插入多條數據
- PHP MySQL 預處理語句
- PHP MySQL 讀取數據
- PHP MySQL Where 子句
- PHP MySQL Order By 關鍵詞
- PHP MySQL Update
- PHP MySQL Delete
- PHP 數據庫 ODBC
- PHP XML
- PHP XML Expat 解析器
- PHP XML DOM
- PHP SimpleXML
- PHP AJAX
- AJAX 簡介
- AJAX XMLHttpRequest
- PHP 和 AJAX 請求
- PHP 和 AJAX XML 實例
- PHP 和 AJAX MySQL 數據庫實例
- PHP 和 AJAX responseXML 實例
- PHP 和 AJAX Live Search
- PHP 和 AJAX RSS 閱讀器
- PHP 和 AJAX 投票
- 免責聲明