小白7天入门PHP Web开发 - Day 5 Ajax实现前后端分离交互
《小白7天入门PHP Web开发》系列文章,面向单纯善良的完全不懂Web开发编程的入门速成课程,小白们如果感兴趣可以研读此系列文章,也可以连线提问。各路大神有何指教还请指点一二。希望各路大神手下留情,注意维护自己的身份和形象。拜谢各位。
上一篇文章 我们 了解PHP的基础语法、PHP如何和前端表单交互、PHP的类和对象、函数等知识,希望你能掌握简单的PHP前后端交互、理解类和函数封装。 这节我们继续上节课讲到的成绩转评级的案例,讲解 JQuery、Ajax的使用实现前后端分离以及与PHP的交互 ,让用户 体验上更好 。
一、回顾一下上节课的交互过程
还记得我们上节课的案例吗?页面长这样的
请求后端处理以后返回的结果是这样的
首先,我们要访问php文件,还记得上节课说的php的环境配置吗,不记得的 回去先看看 。然后看一下我们本节课的目录文件结构。我们本节课访问的地址就是 localhost/day05/ 为根地址。观察上面的图也能看到。
代码的话我们还是照常给大家贴出来(因为我写文章的地点、电脑不固定,所以差别可能在文件的路径上)
<!-- score.html -->
<!-- 使用 localhost/score.html 访问或直接用浏览器打开文件 -->
<!-- score.html文件应与后续.php文件在同一个目录下 -->
<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>成绩转评级</title>
<style type="text/css">
/*通用样式*/
* { font-size: 14px; margin: 0; padding: 0; }
/*说明部分样式*/
.explain { background-color: #f4f4f4; margin-top: 100px; padding: 20px 0px; }
.block { text-align: left; width: 400px; margin: 0 auto; }
.block ul { list-style: none; }
/*表单部分样式*/
.form { width: 400px; margin: 0 auto; margin-top: 20px; }
.form input, .form button {
height: 36px;
box-sizing: border-box;
margin-top: 10px;
padding: 5px 10px;
.form input { width: 100%; }
.form button { width: 100px; }
</style>
</head>
<div class="explain">
<div class="block">
<li>1、 学生成绩90分(含)以上,评级为A</li>
<li>2、 学生成绩在80分(含)以上,90分以下,评级为B</li>
<li>3、 学生成绩在60分(含)以上,80分以下,评级为C</li>
<li>4、 学生成绩在60分以下,评级为D</li>
</div>
</div>
<div class="form">
<form action="apis/scorelevel.php" method="get" accept-charset="utf-8" target="_blank" onsubmit="return checkform()">
<input type="text" name="study_name" value="" placeholder="请输入学生姓名">
<input type="text" name="study_score" value="" placeholder="请输入学生成绩">
<button type="submit">检测评级</button>
</form>
</div>
<script>
function checkform() {
var study_name = document.getElementsByName('study_name')[0].value;
var study_score = document.getElementsByName('study_score')[0].value;
if ( !(study_name && study_score) ) {
alert('学生姓名和学生成绩不能为空');
return false;
</script>
</body>
</html>
<?php
* apis/scorelevel.php
* 我们以 “用户输入学生成绩,根据学生成绩对学生评级并输出” 的功能需求来做示例
* 需求的基本内容:
* 学生成绩90分(含)以上,评级为A
* 学生成绩在80分(含)以上,90分以下,评级为B
* 学生成绩在60分(含)以上,80分以下,评级为C
* 学生成绩在60分以下,评级为D
// 首先考虑,成绩从哪里来?用户输入提交过来的
# 获取用户提交的学生名字和成绩
$study_name = isset($_GET['study_name']) ? $_GET['study_name'] : '';
$study_score = isset($_GET['study_score']) ? $_GET['study_score'] : '';
// 初始化评级
$level = '未知';
$level_label = '未知';
// 检测姓名和分数是否为空
if ( $study_name == '' || $study_score == '' ) {
echo '学生姓名和学生成绩未知,请检查提交的数据是否为空';
die;
// 根据分数给学生评级
if ( $study_score >= 90 ) {
$level = 'A';
} elseif ( $study_score >= 80 && $study_score < 90 ) {
$level = 'B';
} elseif ( $study_score >= 60 && $study_score < 80 ) {
$level = 'C';
} elseif ( $study_score < 60 ) {
$level = 'D';
} else {
$level = '未知';
switch ( $level ) {
case 'A':
$level_label = '优秀';
break;
case 'B':
$level_label = '良好';
break;
case 'C':
$level_label = '及格';
break;
case 'D':
$level_label = '差';
break;
echo '学生 '.$study_name.' 的成绩为 '. $study_score .',评级为:'.$level.'('. $level_label .')';
die;
1、我们分解一下这个交互过程
页面的表单直接将表单提交到 scorelevel.php 后端文件进行处理,这个php文件处理后就直接将结果返回给了浏览器页面。请看下面代码里表单标签 form里的属性 action的值,正是要提交到的页面的文件路径
<div class="form">
<form action="apis/scorelevel.php" method="get" accept-charset="utf-8" target="_blank" onsubmit="return checkform()">
<input type="text" name="study_name" value="" placeholder="请输入学生姓名">
<input type="text" name="study_score" value="" placeholder="请输入学生成绩">
<button type="submit">检测评级</button>
</form>
</div>
现在有一个问题是我们 每次提交表单都会出现一个新的浏览器标签页面 (如果没试过的话尽快尝试一下运行起来),有没有感觉有点不爽,点一次打开个新页面,然后下一个成绩又得去切换再填一次再点一次“检测评级”。好在,我们可以很简单的解决这个问题,就是不打开新的页面,在当前页面提交表单。只需要对html代码稍微修改一下即可
<form action="apis/scorelevel.php" method="get" accept-charset="utf-8" target="_blank" onsubmit="return checkform()">
<!-- 修改为如下代码 -->
<form action="apis/scorelevel.php" method="get" accept-charset="utf-8" target="_self" onsubmit="return checkform()">
实际上就是把表单的属性 target 的值 _blank 改成了 _self ,可以理解为前者是 打开新页面然后提交表单 ,后者是在 当前页面提交表单 ,后者其实是可以省略的,也就是 把整个 target 去掉,跟 target="_self" 效果是一样 的。大家试试就很容易知道这个结果了。
这个时候不打开新页面了。但是有没有发现另外一个问题,就是每次还得返回到表单页面,才能重新再提交新的成绩和学生。是不是还是很烦?怎么办呢?还记得我们说过吗? PHP是解释型脚本语言,是可以嵌入到HTML里面去 的,那么我们有(jue)没(dui)有(you)理由想到,既然是提交到php文件处理,那么如果提交到当前文件,php代码也能处理,那不就是实现了提交到当前页面吗?说干就干,在html代码里把php代码嵌入进来,就是把php代码写进html文件里面,但是!记住了,php代码要能执行,文件名后缀必须是.php。于是,我们有了下面的代码。
<html>
<!-- 这里是HTML代码,和上面的页面一样的部分就不写出来了 -->
<!-- 只修改了表单属性action为空表示提交到当前页面(他自己) -->
<form action="" method="get" accept-charset="utf-8" onsubmit="return checkform()">
<!-- 表单内容代码跟上面的一样 -->
</form>
</html>
<?php
// 1、把php代码的首尾标签协商
// 2、把scorelevel.php里面的php代码直接拷贝(复制粘贴)到这里来就可以了
// some php code
然后我们用浏览器打开链接 localhost/day05/scoresubmit.php
现在我们提交一个表单数据看看结果。
你有没有发现,我们提交到的就是当前页面哦,也能正确输出了。So,我们是不是解决了上面所有的问题了。
那么现在就真的没有问题了吗?(明知故问)我都这么说了,证明肯定还有问题呀~!
第一、每次提交页面会刷新
第二、HTML代码和PHP代码混在了一起,后期维护起来会非常麻烦(当HTML代码很多,php业务代码也很多的时候)虽然现在你还没有发现,但请记住,真的会变得非常困难,这就像你的裤子和衣服一起堆在衣柜的一个格子里,刚开始两三件,问题不大,哪天你买了一百条裤子一百件衣服,这个时候找一条裤子,请发挥你的想象力。
所以说嘛,不论是 用户体验 上还是 代码可维护 性上来讲,我们都应该需要改变。
二、Ajax
为了解决上面的问题,我们有一个 前后端分离 的这样一个概念,还有一个 MVC 的概念。这里我们不做深入讨论,因为这个课程面对的电脑和手机前的你,还不需要深入去了解,但请记住一句话, 他们解决了前端开发人员必须等待后端开发人员开发完业务逻辑后再去完成页面开发(或者反过来)的问题,为前后端开发人员协同开发、提升开发效率、减少前后端相互影响、减轻后端服务器压力、让应用(网站)更易扩展和维护等问题 。需要你最好自主了解一下这两个概念,这里推荐一个典型的MVC PHP框架(框架就是一种能帮助你快速实现业务逻辑不用关注实现路由、数据层等底层东西的一个PHP应用),帮助你从MVC模式开始理解前后端分离,框架名称叫 CodeIgniter 中文网 。
我们还是回到简单一点的内容,我们大多数实现分离和不刷新页面所使用的技术就是 Ajax 了。这个是Javascript的一个功能。
Ajax 即“ A synchronous J avascript A nd X ML ”(异步 JavaScript 和 XML),是指一种创建交互式 网页 应用的网页开发技术。
Ajax = 异步 JavaScript 和 XML 或者是 HTML( 标准通用标记语言 的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
以上引用自百度百科 ajax(Ajax 开发)_百度百科
我们知道Javascript可以直接实现很多功能,包括了ajax,但是使用起来并没有那么方便。所以大佬们就做了一个叫 JQuery(JQ) 的js代码库(放很多优化过的js代码的地方),我们可以直接使用这个库,就可以完成很多js原生写起来比较复杂或代码量比较多的功能了,of course~包括我们的 ajax。
1、引入JQuery
要使用JQuery这个库,当然就必须得先引入、包含,我们有两种方式引入,一个是下载jq文件,然后我们自己用 <script>标签引入,二个是直接使用现有的cdn,以上二选一即可,如下:
<html>
<!-- html code -->
<script src="local/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</body>
</html>
2、使用JQuery封装好的ajax
先上个 JQuery手册 ,方便大家以后查阅JQuery库的相关方法函数。
首先明确我们的 js 代码要写在哪里,推荐写在 </body> 标签前即可。如下:
<html>
<!-- html code -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
// js 代码
</script>
</body>
</html>
使用ajax可以达到不刷新整个网页就能跟后端交互并更新页面内容 。那么怎么使用呢?还记得我们 score.html 页面上有写过的检查表单的js代码吗?
<script>
function checkform() {
var study_name = document.getElementsByName('study_name')[0].value;
var study_score = document.getElementsByName('study_score')[0].value;
if ( !(study_name && study_score) ) {
alert('学生姓名和学生成绩不能为空');
return false;
</script>
当姓名和成绩都有的时候我们就提交表单,现在我们要用jq的ajax来提交表单。需要改一下代码咯。
我们在表单div下新增一点HTML代码,用于最后后端返回的信息的展示
<div class="form">
</div>
<div class="explain">
<div class="block notice">请输入学生姓名和成绩,点击检测评级进行成绩评级</div>
</div>
得到页面如下
修改表单提交属性action,让他提交到js,让js处理表单的提交,顺便改下js函数名
<form action="javascript:void(0);" method="get" accept-charset="utf-8" onsubmit="return submitform()">
然后修改js代码,使用jq的ajax来处理表单提交
<script>
function submitform() {
// 使用jq选择器,获取页面标签dom元素的值
var study_name = $('input[name=study_name]').val()
var study_score = $('input[name=study_score]').val()
// 校验是否已经填写姓名和成绩,没有的话就提示信息
if ( !(study_name && study_score) ) {
// 修改提示信息出的文本颜色为红色
$('.notice').css({color:"red"})
// 把提示信息以文本text的方式填充到notice div中
$('.notice').text('学生姓名和学生成绩不能为空')
// 设置提示3秒后恢复到页面原来提示的文字和样式
setTimeout(function(){
// 修改提示信息出的文本颜色为黑色
$('.notice').css({color:"black"})
// 把提示信息以文本text的方式填充到notice div中
$('.notice').text('请输入学生姓名和成绩,点击检测评级进行成绩评级')
}, 3000)
return false
// 如果已经填写了我们就通过ajax提交表单内容
$.ajax({
url: 'http://localhost/day05/apis/scorelevel.php', // 后端php地址
data: $('form').serialize(), // 提交的数据,表单直接序列化
dataType: 'text', // 返回的数据类型,我们这里直接返回文本就是text了
success: function(responseText) { // 请求成功的时候进行处理
// 修改提示信息出的文本颜色为绿色
$('.notice').css({color:"green"})
// 把提示信息以文本text的方式填充到notice div中
$('.notice').text(responseText)
error: function(err){ // 请求失败的时候进行的处理
console.log(err)