PHP 表单验证

在处理PHP表单时我们须要考虑安全性。

本章节我们将展示PHP表单数据安全处理,为了防止黑客及垃圾信息我们须要对表单进行数据安全验证。

htmlspecialcharsphp54PHP法式员从入门到佛系第二十三弹PHP 表单验证 Bootstrap
(图片来自网络侵删)

在本章节先容的HTML表单中包含以下输入字段: 必须与可选文本字段,单选按钮,及提交按钮:

PHP 表单验证明例

代码为:

<!DOCTYPE HTML&gt; <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, 表单将被提交 - 数据将被验证。
如果表单未提交将跳过验证并显示空缺。

在以上实例中利用输入项都是可选的,即利用户不输入任何数据也可以正常显示。

在接下来的章节中我们将先容如何对用户输入的数据进行验证。