PHP 表单

Wesley13
• 阅读 921

1、一个简单的 HTML 表单 POSt方法

包含两个输入字段和一个提交按钮

<html>
<body>
<form action="welcome.php" method="post">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>

welcome.php:

<?php 
echo 'welcome:'.$_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; 
?>

GET方法
包含两个输入字段和一个提交按钮

<html>
<body>
<form action="welcome.php" method="get">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>

welcome.php:

<?php 
echo 'welcome:'.$_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; 
?>

PS:两个例子仅改变method属性,并且没有对表单数据进行验证

2、GET vs. POST

相同点

GET 和 POST 都创建数组(例如,array( key => value, key2 => value2, key3 => value3, ...))。
此数组包含键/值对,其中的键是表单控件的名称,而值是来自用户的输入数据。都是明文传输

不同点

$_GET 是通过 URL 参数传递到当前脚本的变量数组。
$_POST 是通过 HTTP POST 传递到当前脚本的变量数组

GET方法特点

通过 GET 方法从表单发送的信息,所有变量名和值都显示在 URL 中
GET 对所发送信息的数量有限制,不能超过 2000 个字符。
由于变量显示在 URL 中,把页面添加到书签中也更为方便。
GET 可用于发送非敏感的数据。绝不能使用 GET 来发送密码或其他敏感信息!

POST方法特点

通过 POST 方法从表单发送的信息对其他人是不可见的(所有名称/值会被嵌入 HTTP 请求的主体中,通过抓包可见),并且对所发送信息的数量也无限制
支持高级功能,比如在向服务器上传文件时进行 multi-part 二进制输入。
由于变量未显示在 URL 中,也就无法将页面添加到书签。
开发者偏爱 POST 来发送表单数据。

3、复选框表单提交处理

利用html不识别[]而php识别[]为数组的特性
将表单名字加上[]符号,则在html端还是同名的,但在php端接收到的是一个已选数据数组

4、表单验证

前端javascript验证
正则表达式是一个描述字符模式的对象,是由一系列普通字符和特殊字符组成的能明确描述文本字符串的文字匹配模式。
JavaScript中的RegExp对象和String对象支持正则表达式来进行模式匹配和文本检索等。
在JavaScript中,正则表达式是由一个RegExp对象表示的,可以使用RegExp()构造函数来创建。例如:var pattern=new RegExp(“s$”);也可以使用包含在一对斜杠之间的字符串来定义,例如:var pattern=/s$/;
常见的验证类型
验证数值:纯数字,一定位数的数字,正数,负数,非正数,非负数等。
验证非负数例子

<script>
function check(){
  var pattern=/^[+]?([1-9][0-9]*|0)(\.[0-9]+)?$/;
  var s=document.getElementById("param").value;
  if(!pattern.test(s)){
    document.getElementById("msg").innerHTML="*必须输入非负数!";
  }
  else{
    document.getElementById("msg").innerHTML="*校验通过!";
  }
}
</script>

验证用户名和密码例子

<script>
function check(){
  var pattern_name=/^[a-zA-Z\d]\w{5,9}$/;
  //以字母或数字开头,包括字母数字下划线,长度为6-10位
  var pattern_pwd=/^[a-zA-Z\d_]{6,10}$/;
  //只能包括字母数字或下划线,长度为6-10位
  var name=document.getElementById("name").value;
  var pwd=document.getElementById("pwd").value;
  if(!pattern_name.test(name)){
    document.getElementById("msg_name").innerHTML="*必须以字母或数字开头,包括字母、数字或下划线,长度为6~10位!";
  }
  else{
    document.getElementById("msg_name").innerHTML="*用户名校验通过!";
  }
  if(!pattern_pwd.test(pwd)){
    document.getElementById("msg_pwd").innerHTML="*只能包括字母、数字或下划线,长度6~10位!";
  }
  else{
    document.getElementById("msg_pwd").innerHTML="*密码校验通过!";
  }
}
</script>

验证必填项;验证长度;验证特殊内容的格式;验证两个表单控件的值相等;
验证电子邮箱的格式
var pattern=/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]/;
pattern.test(value);
验证固定电话号码
固定电话号码由区号、号码及分机号组成,中间用“-”隔开。区号为3-4位数字,以0开头;号码7-8位数字;分机号可有可无,如果有分机号,则至少3位数字。可使用正则表达式验证:
var pattern=/^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/;
验证日期时间类型
日期时间类型有许多类型的格式,例如要求符合yyyy-mm-dd HH:MM:SS格式或者yyyy/mm/dd HH:MM:SS格式。可以使用正则表达式结合其方法来进行验证。
正则表达式验证日期时间类型

<script>
function check(){
  var pattern=/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
  var s=document.getElementById("param").value;
  var flag=true;
  r=s.match(pattern);
  if(r==null){
    flag=false;
  }
  else{
    var date=new Date(r[1],r[3]-1,r[4],r[5],r[6],r[7]);
    flag=(date.getFullYear()==r[1])&&((date.getMonth()+1)==r[3])&&(date.getDate()==r[4])&&(date.getHours()==r[5])&&(date.getMinutes()==r[6])&&(date.getSeconds()==r[7]);
  }
  if(flag==false){
    document.getElementById("msg").innerHTML="*日期时间不合法!";
  }
  else{
    document.getElementById("msg").innerHTML="*校验通过!";
  }
}
</script>

后端php验证
在处理 PHP 表单时需要重视安全性!
$_SERVER["PHP_SELF"] 返回当前执行脚本的文件名。$_SERVER["PHP_SELF"] 将表单数据发送到页面本身,而不是跳转到另一张页面。这样,用户就能够在表单页面获得错误提示信息。

">

用户输入的URL为:http://www.example.com/test\_form.php则相当于:
$_SERVER["PHP_SELF"] 变量的利用
$_SERVER["PHP_SELF"] 变量能够被黑客利用!如果页面使用了 PHP_SELF,用户能够输入下划线然后执行跨站点脚本(XSS)。
提示:跨站点脚本(Cross-site scripting,XSS)是一种计算机安全漏洞类型,常见于 Web 应用程序。XSS 能够使攻击者向其他用户浏览的网页中输入客户端脚本。
XSS漏洞利用例子
如果用户在地址栏中键入了如下 URL:" rel="nofollow noopener noreferrer" target="_blank">http://www.example.com/test\_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

">会转换为: 这段代码加入了一段脚本和一个提示命令。实际上, 会转换为:<script>location.href('http://www.hacked.com')</script> trim() 函数 去除用户输入数据中不必要的字符(多余的空格、制表符、换行) stripslashes() 函数 删除用户输入数据中的反斜杠(\\) 利用上面的函数创建一个检测函数
function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

必填字段
检查 $_POST 变量是否为空(通过empty() 函数)
错误变量
保存被请求字段的错误消息
显示错误消息
在 HTML 表单中,在每个被请求字段后面增加了一点脚本。如果需要,会生成恰当的错误消息(如果用户未填写必填字段就试图提交表单):
preg_match() 函数检索字符串的模式,如果模式存在则返回 true,否则返回 false。
if (!preg_match("/^[a-zA-Z ]*$/",$name)) { $nameErr = "只允许字母和空格!"; }
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) {$emailErr = "无效的 email 格式!"; }
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=_|!:,.;]*[-a-z0-9+&@#\/%=_|]/i",$website)) {$websiteErr = "无效的 URL";}

小案例

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>php表单验证</title>

<style>
.error{
color:red;
}
</style>
</head>
<body>
<?php

function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}

// 定义变量并设置为空值
$nameErr = $emailErr = $genderErr = $websiteErr = "";
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = test_input($_POST["name"]);
// 检查名字是否包含字母和空格
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "Only letters and white space allowed"; 
}
}

if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = test_input($_POST["email"]);
// 检查电邮地址语法是否有效
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) {
$emailErr = "Invalid email format"; 
}
}

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 = "Invalid URL"; 
}
}

if (empty($_POST["comment"])) {
$comment = "";
} else {
$comment = test_input($_POST["comment"]);
}

if (empty($_POST["gender"])) {
$genderErr = "Gender is required";
} else {
$gender = test_input($_POST["gender"]);
}
}

?>

<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>">
Name: <input type="text" name="name" value="<?php echo $name;?>">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
E-mail:
<input type="text" name="email" value="<?php echo $email;?>">
<span class="error">* <?php echo $emailErr;?></span>
<br><br>
Website:
<input type="text" name="website" value="<?php echo $website;?>">
<span class="error"><?php echo $websiteErr;?></span>
<br><br>
<label>Comment: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
<br><br>
Gender:
<input type="radio" name="gender" value="female" 
<?php if (isset($gender) && $gender=="female") echo "checked";?>>Female
<input type="radio" name="gender" value="male">Male
<?php if (isset($gender) && $gender=="male") echo "checked";?>
<span class="error">* <?php echo $genderErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>

5、文件上传

允许用户上传文件是一个巨大的安全风险。请仅仅允许可信的用户执行文件上传操作。
上传文件表单

<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" /> <br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

enctype 属性规定了在提交表单时要使用哪种内容类型。在表单需要二进制数据时,比如文件内容,请使用 "multipart/form-data"
上传脚本"upload_file.php"

<?php
if ($_FILES["file"]["error"] > 0){
  echo "Error: " . $_FILES["file"]["error"] . "<br />";
}else{
  echo "Upload: " . $_FILES["file"]["name"] . "<br />";
  echo "Type: " . $_FILES["file"]["type"] . "<br />";
  echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
  echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
?>

通过使用 PHP 的全局数组 $_FILES,可以从客户计算机向远程服务器上传文件。
第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。
$_FILES["file"]["name"] - 被上传文件的名称
$_FILES["file"]["type"] - 被上传文件的类型
$_FILES["file"]["size"] - 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码
上传限制
只能上传 .gif 或 .jpeg 文件,文件大小必须小于 20 kb

<?php
if ((($_FILES["file"]["type"] == "image/gif")|| ($_FILES["file"]["type"] == "image/jpeg")|| ($_FILES["file"]["type"] == "image/pjpeg"))&& ($_FILES["file"]["size"] < 20000)) {
  if ($_FILES["file"]["error"] > 0){
    echo "Error: " . $_FILES["file"]["error"] . "<br />";
  }else {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
  }
} else {
  echo "Invalid file";
}
?>

保存被上传的文件
之前的例子在服务器的 PHP 临时文件夹创建了一个被上传文件的临时副本。这个临时的复制文件会在脚本结束时消失。要保存被上传的文件,需要把它拷贝到另外的位置:
使用move_uploaded_file()函数

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Stella981 Stella981
3年前
PHP导入导出EXCELl,CSV
PHP导入导出Excel,CSVHTML<formaction"{:U('Admin/Unit/importcsv')}"method"post"name"myform"id"myform"enctype"multipart/formdata"<input
Stella981 Stella981
3年前
KaliTools说明书+BurpSuit实战指南+SQL注入知识库+国外渗透报告
!(https://oscimg.oschina.net/oscnet/d1c876a571bb41a7942dd9752f68632e.gif"15254461546.gif")0X00KaliLinux Tools中文说明书!(https://oscimg.oschina.net/oscnet/
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
3年前
From表单提交的几种方式
<body<formaction"https://my.oschina.net/u/3285916"method"get"name"formOne"id"formId"name:<inputtype"text"name"name"pwd:<inputtyp
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这