表单及数据提交:
表单的作用:
用于收集相关信息;html中有专门提交数据的标签,可以很容易的收集用户输入的信息,这个标签有两个重要的属性:action表单提交的地址和method以什么方式提交表单,通常后面是get和post。
通常使用有name属性及type属性值为submit或者image的input按钮来提交数据;button默认的type属性值就是submit,所以他也可以提交数据。
提交方式:
method可以设置表单的提交方式,提交方式有很多种,一般会使用get或post这两种方式提交方式,其区别:
.get:表单数据是通过URL中的?参数传递到服务端的,可以在地址栏看到提交的内容,数据长度有限,因为URL地址长度为2000字符左右,不能使用get发送密码等敏感信息。
.post:表单数据是通过请求体传到服务端的,在界面上是看不到的,可以提交任何类型的数据,包括文件,由于界面上看不到,浏览器不储存,更安全。
服务端接收提交的数据:
在form标签action指定的php文件中使用下面的超全局变量即可获取到form表单中提交的数据:
//$_GET接收URL地址?后面get方式提交过来的数据,其用法是在后面跟上input中name属性值,如:$_GET[username];//$_POST接收以post方式提交过来请求体中的数据,其用法是在后面跟上input中name属性值,如:$_POST[password]; $_REQUEST;//get或post方式提交的数据都能获取到,其用法是在后面跟上input中name属性值,如:$_REQUEST[avatar];
注意:为了便于维护,我们通常将表单数据提交给当前的页面本身,即php代码放到当前html页面前面,action的提交地址也可使用统一的:$_SERVER[‘PHP_SELF’];此时也是便于维护的,行业中对程序应对变化的能力称之为鲁棒性。
<?php// 由于代码执行顺序,在同一个文件中做数据处理时,应当先做判断是否有数据,在有数据的情况下在继续处理数据,通常使用$_SERVER['REQUEST_METHOD']判断提交方式:if($_SERVER['REQUEST_METHOD']==='POST'){var_dump($_POST);};?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!-- 所有选框都应该有name属性,数据才可以正常被php接收使用 --><form action="test.php" method='post'><input type="text" name='username'><input type="password" name='password'><input type="submit" value='登录'></form><!-- 单选框 ,若要实现多选一,那么多个type="radio"的input中name属性值应该设置为相同的:--><form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'><input type="radio" name='sex' value='man'>男<input type="radio" name='sex' value='woman'>女<button>提交</button></form><!-- 复选框 , 如果要提交多个选项,那么在多个type="checkbox"的input中name属性值的后面要加[]来实现多选;若不加[],则不能实现多选,最后一项会把前面的覆盖掉--><form action='<?php //echo $_SERVER['PHP_SELF']; ?>' method='post'><input type="checkbox" name='ball[]' value='篮球'>篮球<input type="checkbox" name='ball[]' value='足球'>足球<input type="checkbox" name='ball[]' value='排球'>排球<input type="checkbox" name='ball[]' value='羽毛球'>羽毛球<input type="checkbox" name='ball[]' value='棒球'>棒球<button>提交</button></form><!-- 下拉选框 ,带有name属性的select标签中包含多个option标签--><form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'><select name="math" id=""><option value="1">激活</option><option value="2">未激活</option><option value="3">未知</option></select><button>提交</button></form><!-- 选文件,type属性值为file的input,且要有name属性 --><form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'><input type="file" name='files'><button>提交</button></form><!-- 注意:表单提交中有value属性的会把value属性的值提交到php中 --></body></html>
php处理数据流程:
处理表单提交过来的数据总结起来有三大步骤:
1.接收数据并校验
2.数据持久化
3.数据响应,如下面一个简单登录页面的服务端处理代码(实际开发中并不会这样嵌套if-else,而是将校验代码封装到一个函数,利用return结束后面代码执行):
//php部分:<?php // $_SERVER['REQUEST_METHOD']判断请求方式的方式来解决代码执行顺序造成数据没有加载完成的问题:if($_SERVER['REQUEST_METHOD']==='POST'){//1.校验数据:// 当没有提交name属性值为username的input时:if(empty($_POST['username'])){echo '输入用户名';}else{// 当没有提交name属性值为password的input时:if(empty($_POST['password'])){echo '输入密码';}else{// 当没有提交name属性值为pass的input时:if(empty($_POST['pass'])){echo '请确认密码';}else{//当两次输入的密码不一致时:if($_POST['password']!=$_POST['pass']){echo '两次输入密码不一致';}else{// 当服务协议提交且值为on时:if(!(isset($_POST['agree']) && $_POST['agree']==='on')){echo '必须同意协议';}else{//2.接收数据:$usernaem=$_POST['username'];$password=$_POST['password'];//3.数据持久化:保存到本地文件或数据库(见下面php操作数据库):file_put_contents('users.txt',$usernaem . '|' . $password . "\n",FILE_APPEND);//为了追加多条数据这里传入常量FILE_APPEND即可。}}}}}}// 为了解决if-else嵌套太深的问题一般将代码这样写:function data(){// 为了下面的提示信息$message能正常显示,这里需要用global把$message设置为全局变量,否则不显示。或者更改 $message ----> $GLOBALS['message']也可以更改message为全局变量。global $message;if(empty($_POST['username'])){$message = '输入用户名';return;};if(empty($_POST['password'])){$message = '输入密码';return;};if(empty($_POST['pass'])){$message = '请确认密码';return;};if($_POST['password']!=$_POST['pass']){$message = '两次输入密码不一致';return;};if(!(isset($_POST['agree']) && $_POST['agree']==='on')){$message = '必须同意协议';return;};$usernaem=$_POST['username'];$password=$_POST['password'];file_put_contents('users.txt',$usernaem . '|' . $password . "\n",FILE_APPEND);//为了追加多条数据这里传入常量FILE_APPEND即可。};//当请求方式正确时调用数据的函数:if($_SERVER['REQUEST_METHOD']==='POST'){data(); };?>//html部分: <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'><table><tr><td><label for="username">用户名</label></td><td><input type="text" name='username' id='username' value='<?php echo isset($_POST['username']) ? $_POST['username'] : '' ?>'></td></tr><tr><td><label for="password">密码</label></td><td><input type="password" name='password' id='password'></td></tr><tr><td><label for="confirm">确认密码</label></td><td><input type="password" name='confirm' id='pass'></td></tr><tr><td></td><td><input type="checkbox" name='agree' id='agree' value='on'>同意协议</td></tr><?php if(isset($message)): ?><tr><td></td><td><?php echo $message; ?></td></tr><?php endif ?><tr><td></td><td><button>注册</button></td></tr></table> </form></body></html>
文件域及文件域中数据处理:
处理文件域中数据思路和处理简单的input数据思路一致,但是需要注意:form中这两个属性应该设置成method=‘post’ ,enctype=‘multipart/form-data’;具体如上传图片例子:
<?php//封装行数的方式接收数据校验持久化:function upload(){//把$message变为全局变量,还可以将下面的$message直接用$GLOBSALS['message']替换也可以提升为全局变量。global $message;if(!isset($_FILES['avatar'])){//判断用户提交的表单中是否有name属性值为avatar的文件域$message='上传失败1';return;};$avatar=$_FILES['avatar'];//将接收到的数据赋值给变量,$avatar在这里的数据结构是:// array(1) {// ["file"]=>// array(5) {// ["name"]=>// string(16) "教程目录.jpg"// ["type"]=>// string(10) "image/jpeg"// ["tmp_name"]=>// string(27) "C:\Windows\Temp\php3124.tmp"//网站临时目录// ["error"]=>// int(0)// ["size"]=>// int(1144467)// }// }// 多个文件上传用循环的方式:因为文件域接收到的数据是以数组的形式储存for($i=0;$i<count($avatar['name']);$i++){if($avatar['error'][$i] != UPLOAD_ERR_OK){//如果 $avarat['error'] !== 0 ,说明上传文件有错误,一般为服务端没有接收到文件,这里的0需要语义化为:UPLOAD_ERR_OK$message='上传失败2';return;};$source = $avatar['tmp_name'][$i];//文件在服务端的临时目录$target = 'events/' . $avatar['name'][$i];//把数据要持久化的文件目录$result = move_uploaded_file($source,$target);//移动服务端临时目录中的文件到需要数据持久化的文件目录,并返回一个布尔值。if(!$result){$message = '上传失败3';return;};};$message='上传成功';};if($_SERVER['REQUEST_METHOD']==='POST'){// 接收一个文件使用超全局成员 $_FILES// var_dump($_FILES);upload();var_dump($_FILES['avatar']);};?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><!-- 注意:如果表单中有文件域,必须将表单的method设置为post enctype设置为multipart/form-dataenctype的默认值为urlencoded 格式为:key1=value1&key2=value2form表单中属性autocomplete='off':关闭input输入时的自动输入提示accept=''可以限制文件域默认选择文件的类型,可以手动选择为 所有文件 值是:MIME type的值,解决不了根本问题--><form action="<?php echo $_SERVER['PHP_SELF']; ?>" method='post' enctype='multipart/form-data'><input type="file" name='avatar[]' multiple><!--注意:当文件域要上传多个文件时,name属性值中后面加[],并且设置multiple属性--><?php if(isset($message)): ?><p><?php echo $message; ?></p><?php endif ?><button>提交</button></form></body></html>
php展示数据(响应):
数据展示思路:文件读取----JSON反序列化-----数组遍历-----php与html混编;
把JSON格式的字符串转化为对象的过程叫做反序列化;
解析字符串:字符串转化为了数组的过程:
<?php// 1.读取test.json的数据或数据库中的数据(见下面php操作数据库):$contents=file_get_contents('test.json');//得到JSON格式的字符串//2.json_decode($contents);//json字符串反序列化,得到的每一项是一个对象,php中访问对象的值用 -> //如果需要返回关联数组,则需要在json_decode($congents,true)中传入第二个参数的值为true:$data=json_decode($contents,true);//得到关联数组数据,作为前端开发者,没必要深入学习php,所以采用关联数组;值为false时:转换为php中的stdClass类型对象?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><!--3.通过foreach遍历关联数组:--><?php foreach($data as $key): ?>//4.将数据响应到页面:执行第一次循环则响应json数据中的第一个{}中的数据,下一次循环以此类推<?php echo $key['id']; ?><?php echo $key['title']; ?><?php echo $key['artist']; ?>//{}中有数组继续遍历:<?php foreach($key['images'] as $src): ?><?php echo $src; ?><?php endforeach ?><?php echo $key['source']; ?><?php echo $key[' id ']; ?<?php endforeach ?></body></html>
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者删除。
笔者:苦海