PHP 表单验证
在处理PHP表单时我们须要考虑安全性。
本章节我们将展示PHP表单数据安全处理,为了防止黑客及垃圾信息我们须要对表单进行数据安全验证。
在本章节先容的HTML表单中包含以下输入字段: 必须与可选文本字段,单选按钮,及提交按钮:
PHP 表单验证明例
代码为:
<!DOCTYPE HTML> <html><head><meta charset=\"大众utf-8\"大众><title>菜鸟教程(runoob.com)</title><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 = \公众造孽邮箱格式\"大众; } } if (empty($_POST[\公众website\公众])) { $website = \"大众\公众; } else { $website = test_input($_POST[\公众website\"大众]); // 检测 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\公众 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> 网址: <input type=\"大众text\"大众 name=\"大众website\"大众 value=\"大众<?php echo $website;?>\公众> <span class=\"大众error\"大众><?php echo $websiteErr;?></span> <br><br> 备注: <textarea name=\公众comment\"大众 rows=\公众5\"大众 cols=\公众40\"大众><?php echo $comment;?></textarea> <br><br> 性别: <input type=\公众radio\"大众 name=\公众gender\"大众 <?php if (isset($gender) && $gender==\"大众female\公众) echo \公众checked\"大众;?> value=\"大众female\"大众>女 <input type=\"大众radio\"大众 name=\公众gender\公众 <?php if (isset($gender) && $gender==\公众male\"大众) echo \公众checked\"大众;?> value=\"大众male\"大众>男 <span class=\公众error\公众> <?php echo $genderErr;?></span> <br><br> <input type=\"大众submit\"大众 name=\"大众submit\公众 value=\"大众Submit\公众> </form><?phpecho \"大众<h2>您输入的内容是:</h2>\"大众;echo $name;echo \"大众<br>\"大众;echo $email;echo \"大众<br>\公众;echo $website;echo \公众<br>\"大众;echo $comment;echo \"大众<br>\公众;echo $gender;?></body></html>
上述表单验证规则如下:
首先让我们先看看纯HTML的表单代码:
文本字段
\公众名字\"大众, \"大众E-mail\"大众, 及\"大众网址\"大众字段为文本输入元素,\"大众备注\"大众字段是 textarea。HTML代码如下所示:
“名字”: <input type=\公众text\"大众 name=\"大众name\"大众>E-mail: <input type=\"大众text\"大众 name=\"大众email\公众>网址: <input type=\"大众text\"大众 name=\"大众website\公众>备注: <textarea name=\"大众comment\公众 rows=\公众5\"大众 cols=\公众40\"大众></textarea>
单选按钮
\"大众性别\公众字段是单选按钮,HTML代码如下所示:
性别:<input type=\"大众radio\"大众 name=\"大众gender\"大众 value=\"大众female\公众>女<input type=\"大众radio\"大众 name=\公众gender\"大众 value=\"大众male\"大众>男
表单元素
HTML 表单代码如下所示:
<form method=\"大众post\"大众 action=\公众<?php echo htmlspecialchars($_SERVER[\"大众PHP_SELF\公众]);?>\公众>
该表单利用 method=\公众post\"大众 方法来提交数据。
什么是 $_SERVER[\公众PHP_SELF\"大众] 变量?
$_SERVER[\公众PHP_SELF\公众]是超级全局变量,返回当前正在实行脚本的文件名,与 document root干系。
以是, $_SERVER[\"大众PHP_SELF\"大众] 会发送表单数据到当前页面,而不是跳转到不同的页面。
PHP表单中需引起看重的地方?
$_SERVER[\"大众PHP_SELF\"大众] 变量有可能会被黑客利用!
当黑客利用跨网站脚本的HTTP链接来攻击时,$_SERVER[\"大众PHP_SELF\公众]做事器变量也会被植入脚本。缘故原由便是跨网站脚本是附在实行文件的路径后面的,因此$_SERVER[\"大众PHP_SELF\公众]的字符串就会包含HTTP链接后面的JavaScript程序代码。
XSS又叫 CSS (Cross-Site Script) ,跨站脚本攻击。恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入个中Web里面的html代码会被实行,从而达到恶意用户的分外目的。
指定以下表单文件名为 \"大众test_form.php\"大众:
<form method=\公众post\"大众 action=\"大众<?php echo $_SERVER[\"大众PHP_SELF\公众];?>\公众>
现在,我们利用URL来指定提交地址 \公众test_form.php\"大众,以上代码修正为如下所示:
<form method=\"大众post\"大众 action=\"大众test_form.php\公众>
这样做就很好了。
但是,考虑到用户会在浏览器地址栏中输入以下地址:
http://www.runoob.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
以上的 URL 中,将被解析为如下代码并实行:
<form method=\"大众post\公众 action=\"大众test_form.php/\公众><script>alert('hacked')</script>
代码中添加了 script 标签,并添加了alert命令。 当页面载入时会实行该Javascript代码(用户会看到弹出框)。 这仅仅只是一个大略的实例来解释PHP_SELF变量会被黑客利用。
请把稳, 任何JavaScript代码可以添加在<script>标签中!
黑客可以利用这点重定向页面到其余一台做事器的页面上,页面 代码文件中可以保护恶意代码,代码可以修正全局变量或者获取用户的表单数据。
如何避免 $_SERVER[\"大众PHP_SELF\"大众] 被利用?
$_SERVER[\"大众PHP_SELF\"大众] 可以通过 htmlspecialchars() 函数来避免被利用。
form 代码如下所示:
<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.runoob.com')</script>
该代码将不会被实行,由于它会被保存为HTML转义代码,如下所示:
<script>location.href('http://www.runoob.com')</script>
以上代码是安全的,可以正常在页面显示或者插入邮件中。
当用户提交表单时,我们将做以下两件事情:
利用 PHP trim() 函数去除用户输入数据中不必要的字符 (如:空格,tab,换行)。利用PHP stripslashes()函数去除用户输入数据中的反斜杠 (\)接下来让我们将这些过滤的函数写在一个我们自己定义的函数中,这样可以大大提高代码的复用性。
将函数命名为 test_input()。
现在,我们可以通过test_input()函数来检测 $_POST 中的所有变量, 脚本代码如下所示:
<?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, 表单将被提交 - 数据将被验证。如果表单未提交将跳过验证并显示空缺。
在以上实例中利用输入项都是可选的,即利用户不输入任何数据也可以正常显示。
在接下来的章节中我们将先容如何对用户输入的数据进行验证。