处理Web表单.docx
- 文档编号:6082887
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:25
- 大小:27.44KB
处理Web表单.docx
《处理Web表单.docx》由会员分享,可在线阅读,更多相关《处理Web表单.docx(25页珍藏版)》请在冰点文库上搜索。
处理Web表单
接着第9章的话题,本章继续展示PHP在用于服务器端时的能力。
首先是PHP环境如何能够方便地集成表单数据,其中包括处理上传数据。
接着讨论生成表单,主要是检验提交的数据并且发送回用户。
另外还要介绍一些防止随意提交表单的技术。
现在正适合引入站点安全方面的问题,因为这与表单提交是相互联系的。
Web表单是对站点最方便的访问方式。
表单是对外开放的,用于把信息上传到服务器。
在开发表单时,程序员必须始终考虑如何处理得到的数据。
本章最后还将处理一些特殊问题。
关于安全和PHP的概述请见
快速提示
Ø 把特定字符转化为HTML实体:
$htmlready=htmlspecialchars($string,$quote_style);
一些常用字符在HTML有特殊含义,它们被转化为相应的HTML实体,从而避免作为HTML代码被解释。
被转化的字符包括和号(&)、双引号(”)或单引号(’)(取决于$quote_style的设置)、小于号(<)和大于号(>)。
完整文档:
Ø 把全部字符转化为相应的HTML实体:
$htmlready=htmlentities($string);
任何包含HTML实体的字符都被转化为对应的实体。
完整文档:
Ø 删除字符串里的HTML标记:
$clean=strip_tags($string,$allow);
字符串里全部HTML标记或PHP标记都被删除,但可选参数$allow里指定的标记除外。
完整文档:
Ø 把新行符转化为HTML分隔符:
$htmlready=nl2br($string);
得到的字符串在所有的新行之前都包含‘
’。
完整文档:
10.1 轻松获取表单数据
PHP的最佳特性之一就是能够非常方便地处理表单数据。
PHP会自动填充两个超全局数组,即$_GET和$_POST,它们分别保存着来自GET或POST的数据。
因此,通过POST发送的名为‘city’的表单项会被保存在$_POST[‘city’]里。
这种特性让创建表单并接收数据变得特别简单。
程序清单10.1.1和10.1.2是两个很简单的范例,它们创建的页面只有两个表单元素:
一个是文本框,另一个是提交按钮。
它们都把提交操作指向自身,显示用户所输入的值,但第一段代码使用GET方法,第二段使用POST方法。
程序清单10.1.1 使用GET方法访问表单数据
php
//IfwehadaGETelementcalled'city',thenechoit:
if(isset($_GET['city'])){
echo"
Yousaidyoucomefrom:
{$_GET['city']}
\n";}
?
>
=$_SERVER['PHP_SELF']? >"method="get"name="f1"> Whatcity/towndoyouhailfrom?
程序清单10.1.2 使用POST方法访问表单数据
php
//IfwehadaPOSTelementcalled'city',thenechoit:
if(isset($_POST['city'])){
echo"
Yousaidyoucomefrom:
{$_POST['city']}
\n";}
?
>
=$_SERVER['PHP_SELF']? >"method="post"name="f1"> Whatcity/towndoyouhailfrom?
与这些数据相关的还有另一个超全局变量$_REQUEST,它包含来自GET和POST的全部数据(还包含cookie数据)。
如果不知道哪个方法在提供数据,使用这个变量将是非常方便的。
在默认情况下,在$_REQUEST中POST数据会覆盖GET数据。
改变初始配置中的variables_order可以改变覆盖次序。
在一般应用中,最好明确是要获得GET还是POST数据,这样可以得到更强健的代码,避免错误变量值带来意外的结果。
另外,有时分别使用GET和POST数据可以完成一些有趣的工作,详情请见本章后面的10.3小节。
10.2 获取表单数据的多维数组
前一小节介绍的自动获取表单数据功能之所以非常强大,是由于PHP能够理解来自表单的多维数组。
通过用PHP风格的数组构造符命名表单字段,PHP实际上是把它们作为数组来处理的。
因此,当一组字段具有同一个名称(如‘comment[]’)时,就会创建一个以字符串comment为索引的数组,如程序清单10.2.1所示。
程序清单10.2.1 从表单获取多维数据
php
//Ifwehavea'cities'fromthePOST,thenloopoveranddisplay:
if(isset($_POST['cities'])){
echo"
Youclaimtohavelivedinthefollowingcities:
";
//Loopovereachcityandoutput
foreach($_POST['cities']as$num=>$val){
echo'
',($num+1),".{$val}\n";
}
echo"
\n";}
?
>
=$_SERVER['PHP_SELF']? >"method="post"name="f1"> Inorder,whatarethemostrecentcitiesyouhavelivedin?
php
//Createadozenformentriestoholdcities:
echostr_repeat('
?
>
在这个范例中,总是会有十来项用于设置城市,即使保持为空白的字段也会被提交为一个空字符串。
因此,如果有人只在第七个位置输入了数据,它在返回的数组里仍然会位于第七个位置。
这很适合处理大量相似数据。
我们还可以指定数组索引,而不是只使用[]让它自动创建。
举例来说,我们可以使用索引address[state]来明确表示数据的含义。
参见程序清单10.2.2。
程序清单10.2.2 使用明确索引的多维表单数据
php
//IfwehaveaPOST,then:
if(count($_POST)){
echo"
Youraddressis:
{$_POST['address']['line1']}
{$_POST['address']['line2']}
{$_POST['address']['line3']}
{$_POST['city']},{$_POST['state']}{$_POST['zip']}
";
}
?
>
=$_SERVER['PHP_SELF']? >"method="post"name="f1"> Pleaseprovideyouraddress: Line1: Line2: Line3: City: State: Zip:
最后,还有一种情况允许我们获取充满数据的数组,这是指多重选项字段。
在XHTML里,我们可以创建多重选项字段,允许用户选择其中任意多项。
为了在PHP中访问这种数据,还是让它们具有以[]结尾的名称,这样这些选项就会以数组形式返回了(参见程序清单10.2.3)。
程序清单10.2.3 获取多重选择的表单输入
php
//IfwehaveaPOST,then:
if(isset($_POST['beer'])){
//Outputallbeersthattheyliked:
$beers=implode(',',$_POST['beer']);
echo"
Wow,youlikethefollowingbeers:
{$beers}
\n";}
?
>
=$_SERVER['PHP_SELF']? >"method="post"name="f1"> Whatareyourfavoritetypesofbeer?
如上所示,由于有了这些变量,PHP在获取表单数据时具有强大的功能、出色的灵活性和非常简单的机制。
10.3 共同使用GET和POST表单数据
由于GET和POST变量集是分别传递的,因此即使其中存在同名变量,我们也可以同时使用它们。
最常见的应用方式是通过GET把一些配置变量传递给脚本,同时允许用户以POST方式输入其他参数。
这在某些情况下会特别有用,因为GET参数是保存在书签里的,而POST参数不是。
因此我们可以在在GET字符串放置一些元素来影响书签的设置,从而获取正确显示页面所需的信息。
程序清单10.3.1展示了这种方法,其中使用GET字符串表示页面已经被提交,但是通过POST发送用户数据。
这样如果用户对已经提交的页面设置了书签,当他返回到这个页面时就会看到一个自定义错误。
程序清单10.3.1 同时使用GET和POST数据
php
//Ifwehavea'GET'parametercalledstateanditissetto'save'
if(isset($_GET['state'])&&($_GET['state']=='save')){
//CheckifthePOSTdataisblank:
if(count($_POST)==0){
//Lookslikeabookmark,theGETexistedbutnopost:
die("ERROR:
Thispagehasbeenimproperlyaccessed.");
}
//Otherwise,outputsomedata:
echo"
Youclaimtoliveinstate:
{$_POST['state']}
\n";echo"
Thescriptinisthe'{$_GET['state']}'state.
\n";}
?
>
=$_SERVER['PHP_SELF']? >? state=save" method="post"name="f1"> Inwhatstatedoyoulive?
10.4 接受上传文件
PHP提供了一种直观的方式来处理文件上传。
当页面上有文件上传字段时,$_FILES数组就会被自动填充,其中包含各种数据。
举例来说,如果上传字段的名称是‘attachment’,那么就会存在以下数据。
n $_FILES[‘attachment’][‘name’]:
来自用户计算机的原始文件名。
n $_FILES[‘attachment’][‘type’]:
文件的MIME类型(如‘text/plain’),但需要浏览器提供这个类型。
n $_FILES[‘attachment’][‘size’]:
文件大小,以字节为单位。
n $_FILES[‘attachment’][‘tmp_name’]:
上传文件的完整文件名。
n $_FILES[‘attachment’][‘error’]:
如果上传过程中有任何错误,这就是错误代码。
利用上述功能,程序清单10.4.1接收一个上传文件,把它保存到自己所在的同一目录里,使用来自用户计算机的原始名称。
程序清单10.4.1 文件上传
php
//Ifwehadanyfiles
if(count($_FILES)){
//Doublecheckthatwereallyhadafile:
if(!
($_FILES['attachment']['size'])){
echo"
ERROR:
Noactualfileuploaded
\n";}else{
//Determinethefilenametowhichwewanttosavethisfile:
$newname=dirname(__FILE__).'/'.
basename($_FILES['attachment']['name']);
//Attempttomovetheuploadedfiletoit'snewhome:
if(!
(move_uploaded_file($_FILES['attachment']['tmp_name'],
$newname))){
echo"
ERROR:
Aproblemoccurredduringfileupload!
\n";}else{
//Itworked!
echo"
Done!
Thefilehasbeensavedas:
{$newname}
\n";}
}
}
?
>
=$_SERVER['PHP_SELF']? >"method="post" enctype="multipart/form-data"name="f1"> Whydon'tyouuploadafile?
函数move_uploaded_file()完成了很多工作,它不仅能够把文件移动到指定位置,还可以进行一些完整性检查,确定文件在传输过程中没有遭到破坏。
另外,我们还要检查文件大小不是0,从而确定文件的确上传了。
如果有人提交了一个在其计算机上并不存在的文件,那么一切过程与真正的上传文件是一样的,只是文件大小是0。
需要说明的是“特意”隐藏起来的表单字段MAX_FILE_SIZE,它有两个作用。
首先,有些Web浏览器实际上会提取这个字段,并且不允许用户上传比这个设置大的文件(以字节为单位)。
这样可以形成很好的用户界面,因为这样会明确表示不允许上传大于一定尺寸的文件,否则用户在上传文件时,必须在经过很多时间之后才能发现文件尺寸过大。
其次,PHP本身也会查看这个值,它会忽略比这个设置大的文件,并且会设置错误代码UPLOAD_ERR_FORM_SIZE。
然而通过操作表单数据可以轻松地绕过这个检查,因此如果想确保不会上传超过标准的文件,就需要亲自检查文件大小。
至少应该让这个值与PHP配置文件里最大上传尺寸的参数一致,后者是由upload_max_filesize设置的,默认值是8MB,或8 388 608字节。
除了PHP参数upload_max_filesize和表单字段MAX_FILE_SIZE需要适当设置,服务器和HTML表单里还需要设置其他一些参数。
在服务器端,PHP参数post_max_size必须比upload_max_filesize大。
另外,上传文件所用的时间也会计入脚本执行时间,因此PHP参数max_execution_time需要设置得足够长,能够上传适当尺寸的文件。
在脚本里利用函数set_time_limit()也可以设置这个参数。
还有一个PHP参数max_input_time,它是脚本解析输入数据时能够使用的最长时间。
如果用户处于慢速连接,或是需要上传一个大文件,就可能超过这个时间限制。
另外一个经常会被忽视的细节是设置服务器上传目录的适当权限,让Web服务器能够实际完成写入操作。
在客户端需要遵守两个规则:
首先是确保表单使用POST方法;第二是表单需要属性enctype=‘multipart/form-data’。
如果不满足这些条件,上传文件就不能实现。
10.5 生成选择语句
Web程序经常需要在同一个Web页面上重复多个选项列表,这可能是国家列表、省市列表、数据类列表等。
更常见的情况是,这些信息可能来自数据库,所以出于性能的考虑,需要只设置一个选项集并且重复使用它。
程序清单10.5.1展示了创建这种重复选项的方法。
程序清单10.5.1 动态生成选项
php
//Ifthisfilewasasubmission,thenoutputthevalues
if(count($_POST)){
echo"
YousubmittedthefollowingmusicIDnumbers:
1st-{$_POST['1st']},2nd-{$_POST['2nd']},3rd-{$_POST['3rd']}
";
}
//Arrayofoptionsinaformatthatmighthavecomefromadatabasequery:
$types=array(
array('id'=>10,'desc'=>'Rock'),
array('id'=>11,'desc'=>'Alternative'),
array('id'=>12,'desc'=>'Metal'),
array('id'=>20,'desc'=>'Classical'),
array('id'=>33,'desc'=>'Jazz'),
array('id'=>34,'desc'=>'Blues'),
array('id'=>42,'desc'=>'Ska'),
array('id'=>44,'desc'=>'Folk'),
array('id'=>49,'desc'=>'BlueGrass')
);
//Now,generatetheoptionsportionofaselectstring,baseduponthis:
//Startwithablankoption:
$options="
//Nowloopoverallpossibilities,addingthemin:
foreach($typesas$m){
$options.="
}
//Andnowwecanoutputourpage,usingthismultipletimes:
?
>
=$_SERVER['PHP_SELF']? >"method="post"name="f1"> Pleasechooseyourfavoritetypesofmusic:
1st:
=$options?
>
2nd:
=$options?
>
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 处理 Web 表单