作为一个计算机系统,输入输出设备作为非核心设备却是不可或缺的,硬件如此,软件亦是如此。试想一台功能强劲的计算机,如果没有输入输出设备,它与一块只能耗电并且发出嗡嗡噪音的废铁有何不同。应用程序的道理也是一样。
在PHP开发的WEB应用程序中,所有非PHP代码以及输出语句中的内容都会被输出,那么程序又是如何接收输入内容的呢?相信不少人一定想到了 WEB表单!在HTTP协议下,输入输出的原型其实是HTTP请求与响应,客户端向服务器端发送的数据称之为请求,反之称为响应。虽然HTTP/1.1定义了7种请求方法,但真正常用的却只有在HTTP/0.9种就已经有的两种方法——GET和POST,它们都允许发送自定义数据给服务器端。因此,可以通过接收这两种方法的请求数据,来实现输入。
一、 $_GET数组
GET是HTTP中最原始的请求方式,在网页中点击一个超级链接或在地址栏输入一个URL都会发送一个GET请求。在GET请求中,数据是后缀在URL后面来发送的,就好像这样: [url]http://www.phpboke.com/request.php?id=root&password=asdfl[/url]。PHP将GET请求封装在了$_GET数组中,请求的变量名是数组的下标,要接收上面那个请求传递的两个变量id和password,使用$_GET['id'] 和$_GET['password']即可。请看下面的例子:
<!– get.php文件 –>
<?php
if($_GET['get']) {
echo $_GET['id'], “<BR>”;
echo $_GET['password'], “<BR>”;
}
?>
<form action=”get.php”>
<label for=”id”>账号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”get” value=”提交”>
</form>
get.php文件中有一个表单,它将使用默认的GET方法发送请求,其效果与上面看到的URL是相同的。请注意文件一开始的PHP代码段:它首先判断请求变量get是否存在(是否点击了name属性为get的提交按钮),如果存在则输出请求的变量。由于在第一次打开文件时,变量get不存在,因此开头的PHP代码根本不会被执行,而直接输出表单。当提交表单后,PHP代码得到执行,用户输入的两个变量也会被输出。
有时候,在程序中并不能确定客户端提交了哪些数据过来,那么怎么样在不知道请求变量名字的前提下遍历请求数据呢?这种屏蔽细节,遍历集合的方法在《设计模式》中被称为迭代(Iterate), PHP中是通过foreach语句来实现的。请看下面的例子:
<!– iterator.php –>
<?php
foreach($_GET as $index => $value) echo “$_GET[$index] = $value”, “<BR>”;
?>
使用iterator.php?id=juxugongzi &password=adsl&address=peking这个链接访问它,将会看到foreach语句将所有用GET方法请求的变量都枚举出来了,而在事先,我们并不知道每个请求变量的名字。
二、 $_POST数组
GET方法的本意就是下载(与其对应的是上传方法PUT),因此并不是专门用于传递数据的,它将请求数据全部经过URL编码后缀在请求资源的后面,这样一来,当数据很多时URL就会变得很长——但这并不是问题的所在,问题所在是一些WEB浏览器或服务器程序会限制这行字符串的长度。这时,就需要用到 POST方法了。
顾名思义,POST方法的主要用途就是“传递”数据,它将数据放在所有请求标题的后面上传,这样一来,无论有多少数据上传都不成问题了(这样请求数据的大小之取决于WEB服务允许的尺寸了)。通常来说,对于表单数据如无特别需要都使用POST方法来上传,这样就无须去关心具体上传数据的尺寸了。
POST方法的请求数据被封装到了$_POST数组中,其使用方法与$_GET数组一样。将上面的表单添加一个method属性,就变成了这样:
<!– post.php文件 –>
<?php
if($_POST['post']) {
foreach($_POST as $index = > $value) echo “$_POST[$index] = $value”, “<BR>”;
}
?>
<form action=”post.php” method=”post”>
<label for=”id”>账号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”post” value=”提交”>
</form>
另一个有趣的设定是,GET方法和POST方法并不矛盾,在POST方法中同样可以传递GET变量,将上面的post.php文件稍微改动一下,就成了这样:
<!– post.php文件 –>
<?php
if($_POST['post']) {
foreach($_POST as $index = > $value) echo “$_POST[$index] = $value”, “<BR>”;
foreach($_GET as $index = > $value) echo “$_GET[$index] = $value”, “<BR>”;
}
?>
<form action=”post.php?act=login” method=”post”>
<label for=”id”>帐号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”post” value=”提交”>
</form>
该程序同时处理了GET方法(act 参数)和POST方法(id 和 password 参数)的请求数据,GET方法的请求变量后缀在了表单action属性值的后面,这样只有一点问题,就是GET方法的请求变量不能由用户来输入。通常,固定的数据使用GET方法,由用户输入的数据使用POST方法来发送,两种方法区分开了不同逻辑的数据。不过读者在构建这种表单的时候,一定要注意两种方法不要有相同的变量名,否则将出现不可预料的后果。最后,需要注意的是,当使用GET方法发送数据时,则 <form>标签 action 属性值中不能包含查询字符串(即使包含也不会生效),所以,下面的表单中,act 参数将不能发送:
<form action=”post.php?act=login” method=”get”>
<label for=”id”>账号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”post” value=”提交”>
</form>
应该改成下面的形式:
<form action=”post.php” method=”get”>
<label for=”id”>账号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”post” value=”提交”>
<input type=”hidden” name=”act” value=”login”>
</form>
三、$_REQUEST数组
使用$_GET和$_POST接收传递来的数据有一个问题,就是程序必须知道上传来的数据具体使用哪种方法。但实际上,无论是哪种方法,都是传递数据给 WEB应用程序,它们的目的是一样的。$_REQUEST数组屏蔽了这些细节,它封装了$_GET、$_POST、$_FILE和$_COOKIE四个数组的内容,使我们对这些数据可以一视同仁。事实上,在JSP中,GET和POST的变量就是统一使用request.getParameter()方法来接收,只不过PHP中的$_REQUEST数组又封装了Cookie的内容。当使用$_REQUEST数组后,上面的例子可以简化成这样:
<!– request.php文件 –>
<?php
if($_REQUEST['post']) {
foreach($_REQUEST as $index = > $value) echo “$_REQUEST[$index] = $value”, “<BR>”;
}
?>
<form action=”request.php?id=juxugongzi&password=adsl” method=”post”>
<label for=”id”>账号:</label><input type=”text” name=”id”>
<label for=”password”>密码:</label><input type=”text” name=”password”>
<input type=”submit” name=”post” value=”提交”>
</form>
不过,使用$_REQUEST数组是一定要注意,几种数据中的变量名不要冲突,尤其要注意的是$_COOKIE,它的数据不使用过客户端来设置的。
总结:
- 在网页中点击一个超级链接或在地址栏输入一个URL都会发送一个GET请求
- 表单,它将使用默认的GET方法发送请求,在表单设置method属性为post,则按post方法发送请求
- 当使用GET方法发送数据时,则 <form>标签 action 属性值中不能包含查询字符串(即使包含也不会生效)
- post方法可以传送很长的数据,当数据很长的时候用post方法
- $_REQUEST数组,它封装了$_GET、$_POST、$_FILE和$_COOKIE四个数组的内容,可以通过$_REQUEST访问这四个数组中的数据