PHP 表单处理
有一点很重要的事情值得注意,当处理 HTML 表单时,PHP 能把来自 HTML 页面中的表单元素自动变成可供 PHP 脚本使用。
下面的实例包含了一个 HTML 表单,带有两个输入框和一个提交按钮。
form.html 文件代码:
<html> <head> <meta charset="utf-8"> <title>表单实例</title> </head> <body> <form action="welcome.php" method="post"> 名字: <input type="text" name="fname"> 年龄: <input type="text" name="age"> <input type="submit" value="提交"> </form> </body> </html>
当用户填写完上面的表单并点击提交按钮时,表单的数据会被送往名为 "welcome.php" 的 PHP 文件处理,表单数据是通过 HTTP POST 方法发送的:
welcome.php 文件代码:
欢迎<?php echo $_POST["fname"]; ?>!<br> 你的年龄是 <?php echo $_POST["age"]; ?> 岁。
通过浏览器访问演示如下:
1.创建表单
使用<form>标记,并在其中插入相关的元素,即可创建一个表单。
表单结构如下:
<form name=”form_name” action="url " method="method" enctype=”value” target=”target_win”>
…….
</form>
属性 | 值 | 描述 |
accept | MIME_type | HTML 5 中不支持。 |
accept-charset | charset_list | 规定服务器可处理的表单数据字符集。 |
action | URL | 规定当提交表单时向何处发送表单数据。 |
autocomplete | on off | 规定是否启用表单的自动完成功能。 |
enctype | 见说明 | 规定在发送表单数据之前如何对其进行编码。 |
method | get post | 规定用于发送 form-data 的 HTTP 方法。 默认是get方式 |
name | form_name | 规定表单的名称。 |
novalidate | novalidate | 如果使用该属性,则提交表单时不进行验证。 |
target | _blank _self _parent _top framename | 规定在 |
通过 get 或者 post 方法都可以获得 Form 的数据,两者主要区别在于以下几方面:
Get(URL传递数据)
· URL 改变,在URL 里显示 HTML Form 参数的 name/value 值。
· 只适合有少量参数的 HTML Form,因为 URL 长度有字符
· 涉及安全性的信息,比如用户密码,不能用 get,因为会在 URL 上显示,不安全。
Post(数据块发送数据)
· URL 不改变,不在 URL 里显示 HTML Form 的数据。
· Form 提交的信息没有长度
· 涉及安全性的信息,如用户密码,应采用 post 方式。
2.表单元素
1)input:类型有文本框,按钮,单选按钮,复选框等。格式如下:
<form>
<input type=”file_name” type=”type_name”>
</form>
值 | 描述 |
button | 定义可点击按钮(多数情况下,用于通过 JavaScript 启动脚本)。 |
checkbox | 定义复选框。 |
file | 定义输入字段和 "浏览"按钮,供文件上传。 |
hidden | 定义隐藏的输入字段。 |
image | 定义图像形式的提交按钮。 |
password | 定义密码字段。该字段中的字符被掩码。 |
radio | 定义单选按钮。 |
reset | 定义重置按钮。重置按钮会清除表单中的所有数据。 |
submit | 定义提交按钮。提交按钮会把表单数据发送到服务器。 |
text | 定义单行的输入字段,用户可在其中输入文本。默认宽度为 20 个字符。 |
2)<select>选择标记,语法如下:
<select name =”name” size=” value” multiple>
<option value =" value " selected>选项1</option>
<option value ="value">选项2</option>
<option value=" value ">选项3</option>
……..
</select>
name表示选择域的名称,size表示列表的行数,value表示菜单选项值,multiple表示以菜单方式显示数据
属性 | 值 | 描述 |
autofocus | autofocus | 规定在页面加载后文本区域自动获得焦点。 |
disabled | disabled | 规定禁用该下拉列表。 |
form | form_id | 规定文本区域所属的一个或多个表单。 |
multiple | multiple | 规定可选择多个选项。 |
name | name | 规定下拉列表的名称。 |
required | required | 规定文本区域是必填的。 |
size | number | 规定下拉列表中可见选项的数目。 |
3)<textarea>文字域标记可以用来创建多行文字域。格式如下:
<textarea name=”name” rows=value cols=value value=”value” warp=”value”>
文字内容……
</textarea>
属性 | 值 | 描述 |
autofocus | autofocus | 规定在页面加载后文本区域自动获得焦点。 |
cols | number | 规定文本区内的可见宽度。 |
disabled | disabled | 规定禁用该文本区。 |
form | form_id | 规定文本区域所属的一个或多个表单。 |
maxlength | number | 规定文本区域的最大字符数。 |
name | name_of_textarea | 规定文本区的名称。 |
placeholder | text | 规定描述文本区域预期值的简短提示。 |
readonly | readonly | 规定文本区为只读。 |
required | required | 规定文本区域是必填的。 |
rows | number | 规定文本区内的可见行数。 |
wrap | hard soft | 规定当在表单中提交时,文本区域中的文本如何换行。。 |
实例:
<form action="" method="post" name="form1" enctype="multipart/form-data"> <table width="405" height="24" border="1" cellpadding="1" cellspacing="1" bordercolor="#FFFFFF" bgcolor="#999999"> <tr bgcolor="#FFCC33"> <td width="103" height="25" align="right">姓名:</td> <td width="144" height="25" align="left"><input name="user" type="text" id="user" size="20" maxlength="100"></td> </tr> <tr bgcolor="#FFCC33"> <td height="25" align="right">性别:</td> <td height="25" colspan="2" align="left"><input name="sex" type="radio" value="男" checked> 男 <input type="radio" name="sex" value="女"> 女</td> </tr> <tr bgcolor="#FFCC33"> <td width="103" height="25" align="right">密码:</td> <td width="289" height="25" colspan="2" align="left"><input name="pwd" type="password" id="pwd" size="20" maxlength="100"></td> </tr> <tr bgcolor="#FFCC33"> <td height="25" align="right">学历:</td> <td height="25" colspan="2" align="left"><select name="select"> <option value="初中">初中</option> <option value="高中">高中</option> <option value="专科">专科</option> <option value="本科" selected>本科</option> <option value="研究生">研究生</option> <option value="博士生">博士生</option> <option value="硕士生">硕士生</option> </select></td> </tr> <tr bgcolor="#FFCC33"> <td height="25" align="right">爱好:</td> <td height="25" colspan="2" align="left"><input name="fond[]" type="checkbox" id="fond[]" value="电脑"> 电脑 <input name="fond[]" type="checkbox" id="fond[]" value="音乐"> 音乐 <input name="fond[]" type="checkbox" id="fond[]" value="旅游"> 旅游 <input name="fond[]" type="checkbox" id="fond[]" value="其他"> 其他</td> </tr> <tr bgcolor="#FFCC33"> <td height="25" align="right">个人写真: </td> <td height="25" colspan="2" align="left"><input name="photo" type="file" size="20" maxlength="1000" id="photo"></td> </tr> <tr bgcolor="#FFCC33"> <td height="25" align="right">个人简介: </td> <td height="25" colspan="2" align="left"><textarea name="intro" cols="28" rows="3" id="intro"></textarea></td> </tr> <tr align="center" bgcolor="#FFCC33"> <td height="25" colspan="3"><input type="submit" name="submit" value="提交"> <input type="reset" name="submit2" value="重置"></td> </tr> </table> </form>
效果:
3.提交表单
1)使用POST方法提交表单
· 将<form>表单的method属性设置成post时,会以不可见的方式传递数据到服务器,并且对发送信息的量也没有限制,而且比较安全。
注释:默认情况下,POST 方法的发送信息的量最大值为 8 MB(可通过设置 php.ini 文件中的 post_max_size 进行更改)。
然而,由于变量不显示在 URL 中,所以无法把页面加入书签。
2)使用GET方法提交表单
· 将<form>表单的method属性设置成get时,传递参数被附加到URL后面传递给服务器。用户是可见的。格式如下:
http://url ? name1=value & name2= value2……
· 参数与URL之间用?隔开,多个参数之间用&隔开。
· 使用get方式提交表单时,URL的长度限制在1MB内。
GET | POST | |
点击返回/刷新按钮 | 没有影响 | 数据会重新发送(浏览器将会提示用户“数据被从新提交”) |
添加书签 | 可以 | 不可以 |
缓存 | 可以 | 不可以 |
编码类型(Encoding type) | application/x-www-form-urlencoded | application/x-www-form-urlencoded or multipart/form-data. 请为二进制数据使用multipart编码 |
历史记录 | 有 | 没有 |
长度限制 | 有 | 没有 |
数据类型限制 | 只允许ASCII字符类型 | 没有限制。允许二进制数据 |
安全性 | 查询字符串会显示在地址栏的URL中,不安全,请不要使用GET请求提交敏感数据 | 因为数据不会显示在地址栏中,也不会缓存下来或保存在浏览记录中,所以看POST求情比GET请求安全,但也不是最安全的方式。如需要传送敏感数据,请使用加密方式传输 |
可见性 | 查询字符串显示在地址栏的URL中,可见 | 查询字符串不会显示在地址栏中,不可见 |
· 在 HTML 表单中使用 method="get" 时,所有的变量名和值都会显示在 URL 中。
注释:所以在发送密码或其他敏感信息时,不应该使用这个方法!
然而,正因为变量显示在 URL 中,因此可以在收藏夹中收藏该页面。在某些情况下,这是很有用的。
4.接收表单数据
1)$_GET 变量
预定义的 $_GET 变量用于收集来自 method="get" 的表单中的值。
form.html 文件代码如下:
<html> <head> <meta charset="utf-8"> <title>表单实例</title> </head> <body> <form action="welcome.php" method="get"> 名字: <input type="text" name="fname"> 年龄: <input type="text" name="age"> <input type="submit" value="提交"> </form> </body> </html>
当用户点击 "Submit" 按钮时,发送到服务器的 URL 如下所示:
http://www.xxx.com/welcome.php?fname=Runoob&age=3
"welcome.php" 文件现在可以通过 $_GET 变量来收集表单数据了(请注意,表单域的名称会自动成为 $_GET 数组中的键):
欢迎 <?php echo $_GET["fname"]; ?>!<br> 你的年龄是 <?php echo $_GET["age"]; ?> 岁。
2)$_POST 变量
预定义的 $_POST 变量用于收集来自 method="post" 的表单中的值。
form.html 文件代码如下:
<html> <head> <meta charset="utf-8"> <title>表单实例</title> </head> <body> <form action="welcome.php" method="post"> 名字: <input type="text" name="fname"> 年龄: <input type="text" name="age"> <input type="submit" value="提交"> </form> </body> </html>
当用户点击 "提交" 按钮时,URL 类似如下所示:
http://www.xxx.com/welcome.php
"welcome.php" 文件现在可以通过 $_POST 变量来收集表单数据了(请注意,表单域的名称会自动成为 $_POST 数组中的键):
欢迎 <?php echo $_POST["fname"]; ?>!<br> 你的年龄是 <?php echo $_POST["age"]; ?> 岁。
3)$_REQUEST 变量
· 预定义的 $_REQUEST 变量包含了 $_GET、$_POST 和 $_COOKIE 的内容。
· $_REQUEST 变量可用来收集通过 GET 和 POST 方法发送的表单数据。
实例:
你可以将 "welcome.php" 文件修改为如下代码,它可以接受 $_GET、$_POST等数据。
欢迎 <?php echo $_REQUEST["fname"]; ?>!<br> 你的年龄是 <?php echo $_REQUEST["age"]; ?> 岁。
提示:使用$_SESSION[]传参的方法获取变量的值,保存之后在任何页面都可以使用。但是这种方法耗费系统资源。
5.表单验证安全
表单的 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()。
<?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 表单验证 - 必填字段
实例:
<!DOCTYPE HTML> <html> <head> <style> .error {color: #FF0000;} </style> </head> <body> <?php // 定义变量并设置为空值 $nameErr = $emailErr = $genderErr = $websiteErr = ""; $name = $email = $gender = $comment = $website = ""; if ($_SERVER["REQUEST_METHOD"] == "POST") { if (empty($_POST["name"])) { $nameErr = "姓名是必填的"; } else { $name = test_input($_POST["name"]); // 检查姓名是否包含字母和空白字符 if (!preg_match("/^[a-zA-Z ]*$/",$name)) { $nameErr = "只允许字母和空格"; } } if (empty($_POST["email"])) { $emailErr = "电邮是必填的"; } else { $email = test_input($_POST["email"]); // 检查电子邮件地址语法是否有效 if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) { $emailErr = "无效的 email 格式"; } } if (empty($_POST["website"])) { $website = ""; } else { $website = test_input($_POST["website"]); // 检查 URL 地址语法是否有效(正则表达式也允许 URL 中的斜杠) if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) { $websiteErr = "无效的 URL"; } } if (empty($_POST["comment"])) { $comment = ""; } else { $comment = test_input($_POST["comment"]); } if (empty($_POST["gender"])) { $genderErr = "性别是必选的"; } else { $gender = test_input($_POST["gender"]); } } function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?> <h2>PHP 验证实例</h2> <p><span class="error">* 必需的字段</span></p> <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> 姓名:<input type="text" name="name"> <span class="error">* <?php echo $nameErr;?></span> <br><br> 电邮:<input type="text" name="email"> <span class="error">* <?php echo $emailErr;?></span> <br><br> 网址:<input type="text" name="website"> <span class="error"><?php echo $websiteErr;?></span> <br><br> 评论:<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">* <?php echo $genderErr;?></span> <br><br> <input type="submit" name="submit" value="提交"> </form> <?php echo "<h2>您的输入:</h2>"; echo $name; echo "<br>"; echo $email; echo "<br>"; echo $website; echo "<br>"; echo $comment; echo "<br>"; echo $gender; ?> </body> </html>
效果如下:
6.对URL传递参数进行编/解码
通过get方式传递参数时,参数直接显示在URL后面,会暴露信息,于是需要进行编码,可以通过urlencode()函数实现,语法如下:
string urlencode(string str)
<a href="index.php?id=<?php echo urlencode("编程词典");?>">PHP编程词典</a>、
进行编码传递参数后,接收参数需要进行解码,需要用到参数urldecode()
string urdecode(string str)
如:
<a href="index.php?id=<?php echo urlencode("编程词典");?>">PHP编程词典</a>
<?php echo "您提交的查询字符串的内容是:".urldecode($_GET[id]);?>
· urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%。
· urldecode()函数与urlencode()函数原理相反,用于解码已编码的 URL 字符串,其原理就是把十六进制字符串转换为中文字符!
· urlencode()编码:对字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。
· urldecode()解码:还原 URL 编码字符串。
示例:
<?php header("Content-Type:text/html; charset=utf-8"); //对参数值进行编码 $parm=urlencode("演示php-mysql"); //拼接url $url="decode.php?par=".$parm; ?> <a href="<?php echo $url;?>">urlencode演示</a> 点击连接后地址栏中汉字被编码了: http://localhost/decode.php?par=%E6%BC%94%E7%A4%BAphp-mysql //decode.php <?php //获取参数值 $parValue=$_GET['par']; //解码 echo urldecode($parValue); //运行结果:演示php-mysql ?>
大部分(99%)的浏览器都会对传过来的值进行urlencode,同时$_GET、$_REQUEST这些都会自动用urldecode解析浏览器传过来的值。
转载请注明: ITTXX.CN--分享互联网 » php基础(十)--表单的使用讲解
最后更新:2019-03-11 18:41:44