表单
在之前学习jQuery-validation插件时,就已经开始接触表单验证了,现在再来学习PHP中的表单,算是顺便的巩固一下前面的东西吧。
表单处理
表单处理需要用到上节提到的两个超全局变量$_GET
和$_POST
来收集表单数据。两者主要区别在于,通过GET方法从表单发送的信息对任何人是可见的(所有变量名和值都显示在URL中),而POST方法发送的信息是对其他人不可见的。这就涉及到安全问题,所以通常来说,开发者用POST来发送表单数据更合理。
在安装wampSERVER后(之前一直不知道怎么用,现在终于派上用场了),实现一个简单的表单。
html 代码:
<!DOCTYPE HTML>
<meta charset=UTF-8>
<html>
<body>
<form action="my_demo.php" method="post">
姓名:
<input type="text" name="name"></br>
邮箱:
<input type="text" name="email"></br>
<input type="submit">
</form>
</body>
</html>
PHP 代码:
<html>
<body>
Welcome <?php echo $_POST["name"]; ?></br>
Your email address :<?php echo $_POST["email"]; ?>
</body>
</html>
结果:
点击提交后,表单数据通过POST方法发送到PHP文件。
注:如果php代码简单的话,可以直接将代码键入到html中
当然,这只是一个最简单的表单,一个完整的表单还应包含表单验证和各种输入限制以及输入提示。
表单安全
$_SERVER["PHP_SELF"]
变量和htmlspecialchars()
函数:
当用户输入非法字符后,页面会弹出提示信息,这时会用到超全局变量$_SERVER["PHP_SELF"]
,它返回的是当前脚本的文件名,所以该变量将表单数据发送到页面本身,而不是跳转到另一张页面。这样,用户就能够在表单页面获得提示信息。值得注意的是$_SERVER["PHP_SELF"]
变量本身能够被黑客利用——用户能够输入下划线然后执行跨站点脚本(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 变量如何被利用的简单无害案例。
解决这种安全问题的办法就是使用htmlspecialchars()函数。
表单代码:
<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>">
无法利用!
表单验证
在用户提交表单时,两件事:
1、(通过 PHP trim() 函数)去除用户输入数据中不必要的字符(多余的空格、制表符、换行)。
2、(通过 PHP stripslashes() 函数)删除用户输入数据中的反斜杠(\)。
用PHP empty()函数来设置验证规则,如果为空,则错误消息会存储于不同的错误变量中。如果不为空,则通过 test_input() 函数发送用户输入数据:
<?php
// 定义变量并设置为空值
$nameErr = $emailErr = "";
$name = $email = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = test_input($_POST["name"]);
}
if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = test_input($_POST["email"]);
}
添加脚本来显示错误信息:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name: <input type="text" name="name">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
E-mail:
<input type="text" name="email">
<span class="error">* <?php echo $emailErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
名字验证:
$name = test_input($_POST["name"]);
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "只允许字母和空格!";
}
E-mail 验证:
$email = test_input($_POST["email"]);
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) {
$emailErr = "无效的 email 格式!";
}
URL 验证:
$website = test_input($_POST["website"]);
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%
=~_|]/i",$website)) {
$websiteErr = "无效的 URL";
}
以上几种验证综合起来就是一个相对完整的表单验证了,以上验证中涉及到的正则表达式需要好好回顾一下,不然看不懂。