[PHP] 03 - Form & Input
PHP 完整表单实例
一、表单示范
二、对应代码
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>菜鸟教程(runoob.com)</title> 6 <style> 7 .error {color: #FF0000;} 8 </style> 9 </head> 10 <body> 11 12 -------------------------------------------------------------------------------------- 13 <?php 14 // (1) 定义变量并默认设置为空值 --> since line 18: 没有报错,有则验证格式 15 $nameErr = $emailErr = $genderErr = $websiteErr = ""; 16 $name = $email = $gender = $comment = $website = ""; 17 18 if ($_SERVER["REQUEST_METHOD"] == "POST") 19 { 20 if (empty($_POST["name"])) 21 { 22 $nameErr = "名字是必需的"; 23 } 24 else 25 { 26 $name = test_input($_POST["name"]); 27 // 检测名字是否只包含字母跟空格,preg_match正则匹配 28 if (!preg_match("/^[a-zA-Z ]*$/",$name)) 29 { 30 $nameErr = "只允许字母和空格"; 31 } 32 } 33 34 ------------------------------------------------------------- 35 if (empty($_POST["email"])) 36 { 37 $emailErr = "邮箱是必需的"; 38 } 39 else 40 { 41 $email = test_input($_POST["email"]); 42 // 检测邮箱是否合法 43 if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) 44 { 45 $emailErr = "非法邮箱格式"; 46 } 47 } 48 49 ------------------------------------------------------------- 50 if (empty($_POST["website"])) 51 { 52 $website = ""; 53 } 54 else 55 { 56 $website = test_input($_POST["website"]); 57 // 检测 URL 地址是否合法 58 if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) 59 { 60 $websiteErr = "非法的 URL 的地址"; 61 } 62 } 63 64 ------------------------------------------------------------- 65 if (empty($_POST["comment"])) 66 { 67 $comment = ""; 68 } 69 else 70 { 71 $comment = test_input($_POST["comment"]); 72 } 73 74 ------------------------------------------------------------- 75 if (empty($_POST["gender"])) 76 { 77 $genderErr = "性别是必需的"; 78 } 79 else 80 { 81 $gender = test_input($_POST["gender"]); 82 } 83 } 84 85 function test_input($data) 86 { 87 $data = trim($data); 88 $data = stripslashes($data); 89 $data = htmlspecialchars($data); 90 return $data; 91 } 92 ?> 93 -------------------------------------------------------------------------------------- 94 <h2>PHP 表单验证实例</h2> 95 <p><span class="error">* 必需字段。</span></p> 96 97 <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> 98 99 名字: <input type="text" name="name" value="<?php echo $name;?>"> 100 <span class="error">* <?php echo $nameErr;?></span> 101 <br><br> 102 E-mail: <input type="text" name="email" value="<?php echo $email;?>"> 103 <span class="error">* <?php echo $emailErr;?></span> 104 <br><br> 105 网址: <input type="text" name="website" value="<?php echo $website;?>"> 106 <span class="error"><?php echo $websiteErr;?></span> 107 <br><br> 108 备注: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea> 109 <br><br> 110 性别: 111 <input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?> value="female">女 112 <input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?> value="male">男 113 <span class="error">* <?php echo $genderErr;?></span> 114 <br><br> 115 <input type="submit" name="submit" value="Submit"> 116 117 </form> 118 -------------------------------------------------------------------------------------- 119 <?php 120 echo "<h2>您输入的内容是:</h2>"; 121 echo $name; 122 echo "<br>"; 123 echo $email; 124 echo "<br>"; 125 echo $website; 126 echo "<br>"; 127 echo $comment; 128 echo "<br>"; 129 echo $gender; 130 ?> 131 132 </body> 133 </html>
提出问题
一、HTTP
Ref: [Node.js] 07 - Html and Http
(1) 提交数据类型判断
$_SERVER['REQUEST_METHOD'] == 'POST'
是判断提交的数据是否是POST方式传来的
之后,通过 _POST["fname"] 获取包里的具体值。
(2) 收集post的值
预定义的 $_POST 变量用于收集来自 method="post" 的表单中的值。
(3) $_GET、$_POST 和 $_REQUEST 的区别?
$_GET 变量接受所有以 get 方式发送的请求,及浏览器地址栏中的 ? 之后的内容。
$_POST 变量接受所有以 post 方式发送的请求,例如,一个 form 以 method=post 提交,提交后 php 会处理 post 过来的全部变量。
$_REQUEST 支持两种方式发送过来的请求,即 post 和 get 它都可以接受,显示不显示要看传递方法,get 会显示在 url 中(有字符数限制),post 不会在 url 中显示,可以传递任意多的数据(只要服务器支持)。
(4) 何时使用 method="get"?
[1] 在 HTML 表单中使用 method="get" 时,所有的变量名和值都会显示在 URL 中。
注释:所以在发送密码或其他敏感信息时,不应该使用这个方法!
[2] 然而,正因为变量显示在 URL 中,因此可以在收藏夹中收藏该页面。在某些情况下,这是很有用的。
注释:HTTP GET 方法不适合大型的变量值。它的值是不能超过 2000 个字符的。
(5) 何时使用 method="post"?
从带有 POST 方法的表单发送的信息,对任何人都是不可见的,并且对发送信息的量也没有限制【其实是8M】。
然而,由于变量不显示在 URL 中,所以无法把页面加入书签。
PHP 表单和用户输入
Ref: http://www.runoob.com/php/php-forms.html
一、PHP 表单处理
当用户填写完上面的表单并点击提交按钮时,表单的数据会被送往名为 "welcome.php" 的 PHP 文件。
[1] 使用post提交
<html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</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>
[2] 服务器当然使用post来自动解析
欢迎 <?php echo $; ?>!<br> 你的年龄是 <?php echo $_POST["age"]; ?> 岁。
二、PHP 获取下拉菜单的数据
可见,这里界面和逻辑未分离。
- 下拉菜单单选
<?php $q = isset($_GET['q'])? htmlspecialchars($_GET['q']) : ''; if($q) { if($q =='RUNOOB') { echo '菜鸟教程<br>http://www.runoob.com'; } else if($q =='GOOGLE') { echo 'Google 搜索<br>http://www.google.com'; } else if($q =='TAOBAO') { echo '淘宝<br>http://www.taobao.com'; } } else { ?> <form action="" method="get"> <select name="q"> <option value="">选择一个站点:</option> <option value="RUNOOB">Runoob</option> <option value="GOOGLE">Google</option> <option value="TAOBAO">Taobao</option> </select> <input type="submit" value="提交"> </form> <?php } ?>
- 下拉菜单多选
<?php $q = isset($_POST['q'])? $_POST['q'] : ''; if(is_array($q)) { $sites = array( 'RUNOOB' => '菜鸟教程: http://www.runoob.com', 'GOOGLE' => 'Google 搜索: http://www.google.com', 'TAOBAO' => '淘宝: http://www.taobao.com', ); foreach($q as $val) { // PHP_EOL 为常量,用于换行 echo $sites[$val] . PHP_EOL; } } else { ?>
------------------------------------------------------------- <form action="" method="post"> <select multiple="multiple" name="q[]"> <option value="">选择一个站点:</option> <option value="RUNOOB">Runoob</option> <option value="GOOGLE">Google</option> <option value="TAOBAO">Taobao</option> </select> <input type="submit" value="提交"> </form> <?php } ?>
三、单选按钮表单
可见,这里界面和逻辑未分离。
<?php $q = isset($_GET['q'])? htmlspecialchars($_GET['q']) : ''; if($q) { if($q =='RUNOOB') { echo '菜鸟教程<br>http://www.runoob.com'; } else if($q =='GOOGLE') { echo 'Google 搜索<br>http://www.google.com'; } else if($q =='TAOBAO') { echo '淘宝<br>http://www.taobao.com'; } } else { ?><form action="" method="get"> <input type="radio" name="q" value="RUNOOB" />Runoob <input type="radio" name="q" value="GOOGLE" />Google <input type="radio" name="q" value="TAOBAO" />Taobao <input type="submit" value="提交"> </form> <?php } ?>
四、checkbox 复选框
可见,界面和逻辑未分离。
<?php $q = isset($_POST['q'])? $_POST['q'] : ''; if(is_array($q)) { $sites = array( 'RUNOOB' => '菜鸟教程: http://www.runoob.com', 'GOOGLE' => 'Google 搜索: http://www.google.com', 'TAOBAO' => '淘宝: http://www.taobao.com', ); foreach($q as $val) { // PHP_EOL 为常量,用于换行 echo $sites[$val] . PHP_EOL; } } else { ?><form action="" method="post"> <input type="checkbox" name="q[]" value="RUNOOB"> Runoob<br> <input type="checkbox" name="q[]" value="GOOGLE"> Google<br> <input type="checkbox" name="q[]" value="TAOBAO"> Taobao<br> <input type="submit" value="提交"> </form> <?php } ?>
五、表单验证
我们应该尽可能的对用户的输入进行验证(通过客户端脚本)。浏览器验证速度更快,并且可以减轻服务器的压力。
如果用户输入需要插入数据库,您应该考虑使用服务器验证。在服务器验证表单的一种好的方式是,把表单的数据传给当前页面(异步提交的方式更好),而不是跳转到不同的页面。这样用户就可以在同一张表单页面得到错误信息。用户也就更容易发现错误了。
【黑客危机】 ----> Line 97
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
[1] htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
-
- & (和号) 成为 &
- " (双引号) 成为 "
- ' (单引号) 成为 '
- < (小于) 成为 <
- > (大于) 成为 >
[2] 什么是 $_SERVER["PHP_SELF"] 变量?
-
- $_SERVER["PHP_SELF"] 是超级全局变量,返回当前正在执行脚本的文件名,与 document root相关。
- $_SERVER["PHP_SELF"] 会发送表单数据到当前页面,而不是跳转到不同的页面。
- $_SERVER["PHP_SELF"] 可以通过 htmlspecialchars() 函数来避免被利用。
详见:http://www.runoob.com/php/php-form-validation.html
六、JavaScript 表单【对比】
关于,界面和逻辑未分离的问题。
只是写法看上去有点类似。JS是运行在浏览器上,而PHP则是纯后端服务器语言。
<!DOCTYPE html> <html>
<head> <meta charset="utf-8"> <script> function validateForm() { var x = document.forms["myForm"]["fname"].value; if (x == null || x == "") { alert("需要输入名字。"); return false; } } </script> </head>
<body> <form name="myForm" action="demo_form.php" onsubmit="return validateForm()" method="post"> 名字: <input type="text" name="fname"> <input type="submit" value="提交"> </form> </body>
</html>