注:本文假定您對運行 PHP 版本 3.0 或更高版本的 Web 服務器具有訪問權。您需要對 PHP 本身以及創建 Html 表單有基本了解。
Html 表單
在閱讀本文的過程中,您將看到不同類型的 Html 表單元素如何提供 PHP 能夠訪問的信息。針對本示例,我使用了一個簡單的信息表單,它由兩個文本域、兩個復選框和一個允許多項的選擇框組成:
清單 1. Html 表單<Html>
<head><title>Tour Information</title></head>
<body>
<h2>Mission Information</h2>
<form action="forMaction.PHP">
<table width="100%">
<tr><td>Ship Name:</td><td><input type="text" name="ship" /></td></tr>
<tr><td>Trip Date:</td><td><input type="text" name="tripdate" /></td></tr>
<tr><td colspan="2">Mission Goals:</td></tr>
<tr>
<td><input type="checkbox" name="exploration" value="yes" />
Exploration</td>
<td><input type="checkbox" name="contact" value="yes" />
Contact</td>
</tr>
<tr>
<td valign="top">Crew specIEs: </td>
<td>
<select name="crew" multiple="multiple">
<option value="xebrax">Xebrax</option>
<option value="snertal">Snertal</option>
<option value="gosny">Gosny</option>
</select>
</td>
</tr>
<tr><td colspan="2" align="center"><input type="submit" /></td></tr>
</table>
</form>
</body>
</Html>
在沒有指定方法的情況下,該表單使用缺省方法 GET ,浏覽器用它將表單值附加到 URL,如下所示:
http://www.vanguardreport.com/forMaction.PHP?
ship=Midnight+Runner&tripdate=12-15-2433&exploration=yes&crew=snertal&crew=gosny
圖 1顯示表單本身。
圖 1. Html 表單
清單 2中顯示的代碼將表單值作為全局變量處理:
清單 2. 作為全局變量的表單值<?PHP
echo "Ship = ".$ship;
echo "<br />";
echo "Tripdate = ".$tripdate;
echo "<br />";
echo "Exploration = ".$exploration;
echo "<br />";
echo "Contact = ".$contact;
?>
生成的 Web 頁面顯示提交的值:
Ship = Midnight Runner
Tripdate = 12-15-2433
Exploration = yes
Contact =
(正如您稍後將看到的那樣,Contact 沒有值,因為沒有選中那個框)。
清單 2 中的表示法當然是方便的,但它僅在 PHP 偽指令 register_globals 被設置為 on 時才可用。在版本 4.2 以前,這是缺省設置,許多 PHP 開發人員甚至沒有意識到有這樣的問題。然而,從版本 4.2 開始, register_globals 的缺省設置是 off ,在此情況下,該表示法不能正常工作,因為不再用適當的值創建並初始化變量。
然而,您可以用其它的方法初始化這些變量。第一個方法是更改 register_globals 的值。許多使用共享服務器的開發人員無權為整個服務器更改該值,但可以針對某個特定站點改變行為。如您有 .htAccess 文件的訪問權,您可以通過添加以下偽指令啟用 register_globals :
PHP_flag register_globals on
鑒於對該特性是否可用的不確定性,建議開發人員最好不要使用或依靠這種獲取變量的方法。那麼您有什麼選擇呢?
如果您的系統運行的是版本 4.1 或更高版本,則您的另一個選擇是使用 import_request_variables() 有選擇地注冊全局變量集合。您可以使用該函數導入 get、post 和 cookIE 值,而且如果您願意的話,還可以給每項添加前綴。例如:
<?PHP
import_request_variables(gp, "formval_");
echo "Ship = ".$formval_ship;
echo "<br />";
echo "Tripdate = ".$formval_tripdate;
echo "<br />";
echo "Exploration = ".$formval_exploration;
echo "<br />";
echo "Contact = ".$formval_contact;
?>
這裡,導入了 get 和 post 值 — 使用 c 來導入 cookIE 值 — 而且由於 p 跟在 g 之後,所以 post 值將覆蓋同名的 get 值。
但如果您象許多開發人員一樣 沒有運行版本 4.1 或更高版本,那怎麼辦呢?
訪問表單值集合
對於那些運行較早版本或不願使用全局變量的人來說,可以選擇使用 $HTTP_GET_VARS 和 $HTTP_POST_VARS 數組。盡管並不贊成使用這些集合,但它們仍然可用,而且仍被廣泛使用。當真的不再使用它們時,將用版本 4.1 中添加的 $_GET 和 $_POST 數組替代它們。
這兩類數組的類型都是散列表(hash table)。 散列表是通過字符串值而不是整數來建立索引的數組。使用表單時,可以通過值的名稱來訪問值,如 清單 3所示:
清單 3. 通過散列表訪問表單值<?
$ship_value = $HTTP_GET_VARS['ship'];
echo $ship_value;
echo "<br />";
$tripdate_value = $HTTP_GET_VARS['tripdate'];
echo $tripdate_value;
echo "<br />";
$exploration_value= $HTTP_GET_VARS['exploration'];
echo $exploration_value;
echo "<br />";
$contact_value = $HTTP_GET_VARS['contact'];
echo $contact_value;
?>
使用該方法,您可以通過名稱來檢索每個字段的值。
單名,多值
到現在為止,每個名稱僅對應一個值。如果有多個值會怎樣?例如,crew specIEs 列表框允許用名稱 crew 提交多個值。
理想情況下,您希望將這些值作為數組使用,這樣就可以顯式地檢索它們。要實現這一點,您必須對 Html 頁面稍加改動。要作為數組提交的字段應該用方括號命名,如 crew[] 中:
清單 4. 修改 Html 頁面...
<td>
<select name="crew[]" multiple="multiple">
<option value="xebrax">Xebrax</option>
<option value="snertal">Snertal</option>
<option value="gosny">Gosny</option>
</select>
</td>
...
一旦您作出更改,檢索表單值實際上產生數組:
清單 5. 將變量作為數組訪問...
$crew_values = $HTTP_GET_VARS['crew'];
echo "0) ".$crew_values[0];
echo "<br />";
echo "1) ".$crew_values[1];
echo "<br />";
echo "2) ".$crew_values[2];
...
現在,提交頁面後會顯示多個值:
0) snertal
1) gosny
2)
首先要注意這是一個下標從 0 開始的數組。第一個遇到的值在位置 0 中,接下來的值在位置 1,以此類推。在本例中,我只提交了兩個值,所以第三項為空。
通常,您不知道將提交多少項,因此您可以利用它是數組這一事實使用 sizeof() 函數來確定提交了多少值,而不必直接調用每一項:
清單 6. 確定數組的大小...
for ($i = 0; $i < sizeof($crew_values); $i++) {
echo $crew_values[$i];
echo "<br />";
}
...
然而,有時問題不是值太多,而是根本沒有值。
令人驚奇的消失的復選框
復選框只有實際被選中時才被提交,認識到這一點很重要。否則,它的消失將告訴您所需知道的實情:用戶沒有單擊復選框。使用復選框時,您可以使用 isset() 函數顯式地檢查是否設置了值:
清單 7. 檢查是否提交了復選框...
$contact_value = $HTTP_GET_VARS['contact'];
echo $contact_value;
if (isset($contact_value)) {
//The checkbox was clicked
} else {
//The checkbox wasn't clicked
}
...獲取所有表單值
復選框字段只是您對預期表單值名稱可能不完全有把握的情形的示例之一。通常,您會發現有一個以通用方法訪問所有表單值的例程是很有用的。
幸運的是,因為 $HTTP_GET_VARS 及其同類只是散列表,您可以用數組的一些特性來操作它們。例如,您可以使用 array_keys() 函數來獲取所有潛在值名稱的列表:
清單 8. 獲取表單值名稱的列表...
$form_fIElds = array_keys($HTTP_GET_VARS);
for ($i = 0; $i < sizeof($form_fIElds); $i++) {
$thisField = $form_fIElds[$i];
$thisValue = $HTTP_GET_VARS[$thisFIEld];
echo $thisFIEld ." = ". $thisValue;
echo "<br />";
}
...
在本例中,您實際上結合了幾種技術。首先,檢索表單字段名稱的數組並將其命名為 $form_fields 。 $form_fIElds 數組只是一個典型的數組,因此您可以使用 sizeof() 函數來確定潛在鍵的數目,並對每一項進行循環遍歷。對於每一項,檢索字段的名稱然後使用該名稱獲取實際值。生成的 Web 頁面看起來如下:
ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = Array
這裡有兩個重要事項。第一,contact 字段根本沒有返回值,這正如預期的那樣。第二,crew 值(順便說一下,您或許知道:它的名稱是 crew 而不是 crew[] )是一個數組而不是值。為了實際檢索所有值,需要使用 is_array() 函數檢測所有數組並相應地處理它們:
清單 9. 處理數組...
for ($i = 0; $i < sizeof($form_fIElds); $i++) {
$thisField = $form_fIElds[$i];
$thisValue = $HTTP_GET_VARS[$thisFIEld];
if (is_array($thisValue)){
for ($j = 0; $j < sizeof($thisValue); $j++) {
echo $thisFIEld ." = ". $thisValue[$j];
echo "<br />";
}
} else {
echo $thisFIEld ." = ". $thisValue;
}
echo "<br />";
}
... 結果是所有已實際提交的數據:
ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = snertal
crew = gosny
最後一個說明:點
既然您有了能適應您提交任何表單值的表單操作頁面,您就需要抽一點時間考慮一個常常讓 PHP 程序員感到意外的情形。
有些情況下,設計人員會選擇使用一個圖形按鈕而不是提交按鈕,圖形按鈕如 圖 2所示,代碼如 清單 10所示。
清單 10. 添加圖形按鈕...
<tr>
<td valign="top">Crew specIEs: </td>
<td>
<select name="crew[]" multiple="multiple">
<option value="xebrax">Xebrax</option>
<option value="snertal">Snertal</option>
<option value="gosny">Gosny</option>
</select>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="image" src=/School/UploadFiles_7810/201104/20110428110859969.gif" name="formbutton"/>
</td>
</tr>
</table>
...
圖 2. 表單上的圖形按鈕
請注意,盡管上圖中只有一個圖像,卻有兩個圖形按鈕(或期望的結果)。作為開發人員,您可以通過檢查和值一同返回的 x 和 y 坐標知道用戶單擊了何處。事實上,按原樣提交該表單可能會創建以如下所示結尾的 URL 和查詢字符串:
...snertal&crew%5B%5D=gosny&formbutton.x=37&formbutton.y=14
請注意附加到按鈕名稱的 .x 和 .y。然而,如果您打算提交該頁面然後查看結果,您會看到:
ship = Midnight Runner
tripdate = 12-15-2433
exploration = yes
crew = snertal
crew = gosny
formbutton_x = 37
formbutton_y = 14
請注意,點號(.)已被轉換成下劃線(_)。這似乎有點奇怪,但它是必要的,因為 PHP 中的變量名不能有點號,因此 $formbutton.x 會是一個非法變量名。事實上,表單名稱中的任何點號 — 不僅僅針對圖像按鈕 — 都被轉換成下劃線。
結束語
在本文中,您看到了對用戶通過 Html 或 XHtml 表單提交的信息進行訪問的幾種方法。如何處理該信息取決於您使用的 PHP 版本和您是否能將表單變量作為全局變量進行訪問。無論何種情況,表單值可作為數組使用,並且您可以用數組的特性來循環遍歷所有可用的值。