第一关: HTML(3)、CSS(5) —— 静态页面
第二关: JS(7)、DOM(6.5)、jQuery(6) —— 用户交互
第三关: AJAX(9)、HTML5(6)、Bootstrap(5) —— 准全栈
第四关: 框架
特点:内容散、主题散、难度大、前四天都是迷茫的
今日目标:
(1)服务器概述 —— 了解
(2)数据库服务器 —— 难点&重点
1.如何访问服务器
协议(语言):// 地址 / 端口号(门牌号)
B KB MB GB TB PB EB ZB YB |
2.数据库服务器的种类
(1)网状数据库
(2)树型数据库
(3)关系型数据库 —— 主流
服务器端程序:负责保存管理数据
客户端程序:负责向服务器发起增删改查指令
(4)对象型数据库
关系型数据库中数据结构:
SERVER => DATABASE => TABLE => ROW => COLUMN
MySQL的两个版本:
(1)Oracle - MySQL
(2)Maria基金会 - MariaDB
XAMPP套装: http://xampp.org
3.使用MySQL服务器的步骤 —— 重点
(1)服务器端:下载并安装MySQL服务器端程序
C:\xampp\mysql\bin\mysqld.exe 精灵/守护程序
(2)服务器端:启动MySQL的服务器程序——售货员上岗
确保3306端口已打开
--------------------------------------------
(3)客户端:下载并安装MySQL客户端程序
C:\xampp\mysql\bin\mysql.exe 注意和服务器程序的区别
(4)客户端:启动客户端程序,连接到服务器上
C:\xampp\mysql\bin\mysql.exe -uroot -p
若设置了Path系统变量,可以简写:
mysql -uroot
(5)客户端:向服务器发送操作指令,实现增删改查数据
SHOW DATABASES; //显示服务器上已有的数据库
.....
练习:反复练习熟悉MySQL服务器的“登录-查看-退出”过程
4.常用的SQL语句
向服务器提交SQL语句有两种方式:
(1)交互模式: 输入一行提交执行一行...,适合于执行少量的语句。
1)连接到服务器 mysql -uroot -p
2)输入一行命令,添加一个分号,回车执行
3)输入一行命令,添加一个分号,回车执行
(2)脚本模式: 把所有的语句编写在一个文本文件中,一次性全部提交给服务器执行,适合于执行批量多条语句。
1)创建一个文本文件
2)开始编写所有的语句
3)把整个文本文件提交给服务器执行
mysql -uroot < e:/x.sql
Structured Query Language, 结构化查询语言,最早由IBM提出的用于操作关系型数据库语言,实现增删改查功能;后来由ISO采纳为行业标准语言,当前主流的关系型数据库(如SQLite、MySQL、SQLServer、Oracle、DB2等)都支持SQL语言标准。 |
SQL语句编写时需要注意:
(1)命令不区分大小写,习惯上关键字都大写,非关键字都小写
(2)所有语句都必须以分号结尾
(3)注释有两种:单行注释(#开头),以及多行注释(/**/)
(4)插入记录行时,字符串/日期数据必须使用单引号;数字类型可用单引号也可不用;关键字(如NULL/TRUE/FALSE)数据不能使用单引号。
数据库乱码问题解决办法: (1)SET NAMES UTF8; (2)CREATE DATABASE xx CHARSET=UTF8; (3).sql文件必须另存为UTF-8编码 (4)必须在交互模式下查询! |
课下练习:
创建jd.sql文件,根据要求编写必需的SQL语句
1)设置SQL编码方式
2)删除数据库-jd,如何存在的话
3)创建数据库-jd,指定字符编码方式
4)开始使用数据库-jd
5)创建产品信息表-product(pid-编号, pname-名称, price-单价,isOnSale-是否特价, pic-产品图片文件路径)
6)向产品表中插入3行记录
7)创建产品评论表-comment(cid, userName-用户名, phone-用户联系电话, content-评论内容, pubTime-发布时间, productId-所评论的产品编号)
8)为每个产品添加两三条评论
9)查询所有产品
10)查询出价格大于1000且小于5000的所有商品(提示:两个查询条件可以使用AND或OR进行组合)
11)查询所有评论
12)查询出1号产品的所有评论
13)删除1号商品及所有评论
14)修改2号商品编号为200,同时修改其所对应的所有评论
数据库mysql语句案例
/*** *SERVER -> DATABASE -> TABLE -> ROW -> COLUMN ****/
#1.设置下面所有的SQL语句的编码方式 SET NAMES UTF8; #2.试着删除数据库taobao(如果存在的话) DROP DATABASE IF EXISTS taobao; #3.重新创建数据库taobao,指定保存数据所有字符集为UTF8 CREATE DATABASE taobao CHARSET=UTF8; #查询出服务器当前已有的所有数据库 #SHOW DATABASES; #4.开始使用指定的数据库/进入指定的数据库 USE taobao;
#5.创建保存用户信息的表(TABLE) CREATE TABLE tb_user( uid INT PRIMARY KEY AUTO_INCREMENT, #用户编号,主键列(不允许出现重复值或NULL),自增列 uname VARCHAR(6), #variable character upwd VARCHAR(32), #用户密码 pic VARCHAR(32), #用户头像图片的路径 score FLOAT(10,2), #用户积分99999999.99 regTime BIGINT #注册时间,一般是大整数代替DATE/DATETIME表示日期时间 );
#向表中插入记录行(ROW) INSERT INTO tb_user VALUES( NULL,'tom','123456','img/101.jpg','111','1234567890125' ); INSERT INTO tb_user VALUES( NULL,'mariab','123456','img/102.jpg','222','1434567890125' ); INSERT INTO tb_user VALUES( NULL,'tomcruise','123456','img/103.jpg','333','1534567890125' ); INSERT INTO tb_user VALUES( NULL,'唐牧','123456','img/201.jpg','111','1234567890125' ); INSERT INTO tb_user VALUES( NULL,'超级玛丽噢哦','123456','img/202.jpg','222','1434567890125' ); INSERT INTO tb_user VALUES( NULL,'一二三四五六七','123456','img/303.jpg','333','1534567890125' ); #INSERT INTO tb_user VALUES( # 101,'king','123456','img/999.jpg','333','1534567890125' #);
#删除一行指定的记录 #DELETE FROM tb_user; #删除表中所有的记录行 #DELETE FROM tb_user WHERE uid===1; 语法错误 #DELETE FROM tb_user WHERE uid==1; 语法错误 DELETE FROM tb_user WHERE uid=1;
#修改一行指定的记录 —— 很容易忘记! #UPDATE tb_user SET uname='马丽亚',upwd='456789'; 修改所有的记录行 UPDATE tb_user SET uname='马丽亚',upwd='456789' WHERE uid=2;
#查询出表中的数据 #SELECT uid,uname,upwd,pic,score,regTime #FROM tb_user;
SELECT * FROM tb_user WHERE uid=2; |
复习:
服务器概述
协议 :// 服务器地址 : 端口
数据库服务器
常见的数据库:SQLite、MySQL、SQLServer、Oracle、DB2
使用步骤:
服务器端:安装(mysqld.exe)、启动(3306)
客户端:安装(mysql.exe)、连接服务器(mysql -uroot)
SQL语句的运行模式:
(1)交互模式
(2)脚本模式
练习:
#1. 设置SQL语句的编码格式
#2. 删除数据库dangdang
#3. 创建数据库dangdang,指定存储数据所用的编码
#4. 进入数据库
#5. 创建表 dd_category(cid, cname, count)
#6. 添加三行记录,三个书籍分类(10/20/30)
#7. 查询出所有的书籍分类
#8. 创建表 dd_book(bid,title,pic,price,pubDate,isOnsale,categoryId)
#9. 为每种分类添加两三条记录
#10. 查询出所有的书籍
#11. 查询出所有的“计算机”类书籍
#12. 删除10号分类及其下所有的书籍
#13. 删除编号为6的书籍,需要修改对应分类的书籍数量
今日目标:
(1)Web服务器概述——着重了解
(2)PHP基础语法——重点
(3)使用PHP连接MySQL——最重点&难点
1.Web服务器概述
Web服务器用于:
(1)接收客户端的请求
(2)理解请求,找到客户端需要的文件
(3)把客户端请求的文件输出给客户端
Web服务器的分类:
(1)静态Web服务器:
提供的内容在任何时间由任何人访问都是完全相同的!
所包含技术:HTML、CSS、JS、Flash、Gif、音视频
常见的静态Web服务器:
Apache Httpd
Microsoft IIS
NginX
(2)动态Web服务器:
提供的内容在不同时间由不同人访问是变化的!
所包含的技术:
JSP = HTML + Java
PHP = HTML + Php
ASP.NET = HTML + C#
Node.js = HTML + NodeJS
2.PHP服务器的搭建
(1)服务器端:下载并安装一款静态Web服务器
C:\xampp\apache\bin\httpd.exe
(2)服务器端:下载并安装PHP语言的解释器
C:\xampp\php\php.exe
推荐使用软件套装(如XAMPP/WAMP等)完成上述两步
(3)服务器端:编写网页,保存在htdocs目录
C:\xampp\htdocs\
(4)服务器端:启动Web服务器,等待客户端发起请求
确保80端口被httpd.exe占用
------------------------------------------
(5)客户端:向服务器发起请求,获取服务器端响应内容
http://服务器的域名或IP地址:80
http://127.0.0.1:80 127.0.0.1指代当前计算机
ipconfig:用于查看当前计算机的IP地址信息 |
练习:编写一个.html文件,保存在htdocs目录下,让同桌访问该网页
练习:
(1)创建一个1.php,向客户端输出50个*
(2)创建一个2.php,向客户端输出10行50列的*
(3)创建一个3.php,向客户端用*输出一个三角形
*
**
***
****
(4)创建一个4.php,使用PHP向客户端输出一个九九乘法表(放在TABLE元素中)
(5)创建一个5.html,使用JS向客户端输出一个九九乘法表(放在TABLE元素中)
JSP - 1995
ASP.NET - 2000
PHP - 1996
Node.js - 2013
3.面试题:如何自学一门编程语言?掌握一门语言的步骤?
(1)了解背景: 历史、现状、趋势、特点、应用领域
Personal Home Page, ZendEngine
PHP: Hypertext Preprocessor
(2)搭建运行环境,写出HelloWorld
(3)数据类型
(4)变量和常量
(5)运算符
(6)逻辑结构
(7)通用小程序
(9)函数和对象
(10)常用预定义函数、对象、组件、第三方工具、框架
(11)实用小项目
4.PHP基础语法——数据类型
JS中的数据类型:
(1)基础值类型:number、string、boolean、undefined
(2)引用/对象类型:....
PHP中的数据类型:
(1)值/标量类型
string 双引号字符串中的变量会被转换为值
boolean: true/TRUE/false/FALSE
int/integer
float/double
(2)复合类型
object
array PHP数组不是对象!不能用echo输出!分为索引数组和关联数组
(3)特殊类型
null / NULL
resource
练习:创建一个二维数组,保存5个商品的信息,每个商品都有pid、pname、price、birthday,isOnsale, pic属性,把这些信息输出在一个TABLE元素中 —— 有坑!小心绕过!
5.PHP基础语法——运算符
算术运算: + - * / %
比较运算:
逻辑运算:
位运算:
三目运算: ? :
字符串拼接: . .=
6.PHP基础语法——变量和常量
声明变量: $变量名 = 值;
声明常量: const 常量名 = 值; //PHP5.4+
define('常量名', 值); //PHP5.3-
7.PHP基础语法——逻辑结构
选择结构:
if... else ...
switch... case...
循环结构:
while...
do... while...
for...
foreach
foreach(数组名 as 值变量名){ }
foreach(数组名 as 下标变量名=>值变量名){ }
8.PHP基础语法——函数的使用
function add($num1, $num2){
$sum = $num1 + $num2;
return $sum;
}
注意:函数内默认是无法使用外部的全局变量的!必须使用global声明一下才可以使用!
$x = 10;
function f1(){
global $x;
}
练习:创建一个函数randColor,返回一个字符串形如: 'rgb(210,99,195)',多次调用该函数。
提示:PHP中生成一个随机数使用rand()
9.PHP中常用函数 —— 数据库连接函数 —— 重点
PHP提供了大量的应用函数,查找手册“函数参考”。
PHP为了连接MySQL数据库,提供了多套函数,比如:
mysql_connect() 早期的函数库;
mysqli_connect() Improved,mysql库的性能提升版;
PHP连接数据库的步骤——与命令行中交互模式下连接数据库步骤一样:
(1)连接到MySQL服务器
$conn = mysqli_connect(....);
(2)发送SQL命令提交给MySQL服务器
$result = mysqli_query($conn,$sql);
(3)查看MySQL服务器返回的执行结果
练习:使用PHP实现新闻的添加和删除功能
(1)编写SQL,创建数据库ifeng,创建表news( nid, title-标题, content-内容, count-浏览次数, pubTime-发布时间 ),插入两行测试数据。
(2)创建PHP,news_add.php,接收客户端提交的新闻编号:title、content、count、pubTime等数据,连接数据库,提交INSERT,输出添加成功或失败。
(3)创建HTML,news_add.html,包含一个表单,让用户输入要添加的新闻内容,点击“提交”按钮,把用户输入提交给news_add.php实现新闻添加。
(4)创建PHP,news_delete.php,接收客户端提交的新闻编号:nid,连接数据库,提交DELETE,输出删除成功或失败。
(5)创建HTML,news_delete.html,包含一个表单,“请输入要删除的新闻的编号:”,点击“提交”按钮,把用户输入提交给news_delete.php实现新闻删除。
复习:
Web服务器
静态: HTML/CSS/JS/SWF/音视频 —— 客户端执行
动态: JSP/PHP/ASPX/Node.js —— 服务器端执行
PHP基础语法:
数据类型:
值类型:string boolean int float
复合类型:object array
特殊类型:null resource
运算符: . =>
逻辑结构: foreach($list as $k=>$v){ }
函数: function add($num1){ return ...; }
PHP操作MySQL:
(1)连接数据库服务器
$conn = mysqli_connect()
(2)提交SQL命令
$sql = "";
$result = mysqli_query($conn,$sql)
(3)查看执行结果
if()....
(4)关闭连接 —— 可以省略
mysqli_close($conn)
练习:
(1)编写SQL:huimaiche.sql,创建数据库huimaiche,表car( cid, cname, pic, price, isonsale, birthday ),试着添加两条记录
(2)编写PHP:car_add.php,接收客户端提交的cname, pic, price, isonsale, birthday,执行INSERT语句,把汽车信息添加到数据库中
(3)编写HTML:car_add.html,提供一个表单,让用户输入汽车信息,提交给car_add.php,实现汽车添加功能
(4)编写PHP:car_delete.php,接收客户端提交的cid,执行DELETE语句,把汽车信息从数据库中删除
(5)编写HTML:car_delete.html,提供一个表单,让用户输入待删除的汽车编号,提交给car_delete.php,实现汽车删除功能
今日目标:
(1)扩展学习PHP中常用函数 —— 掌握
(2)完整的CRUD功能点 —— 重点
(3)HTTP协议 —— 理论知识
1.扩展PHP常用函数
@ 放在一行的开头,用于压制此行的警告消息
die() 终止页面的执行,输出一个错误消息
mysqli_insert_id($conn) 返回刚刚执行的INSERT语句产生的自增编号
mysqli_affected_rows($conn) 返回刚刚执行的DML语句影响的行数
mysqli_fetch_row($result) 从结果集中抓取一行(索引数组)
mysqli_fetch_assoc($result) 从结果集中抓取一行(关联数组)
mysqli_fetch_all($result, MYSQLI_ASSOC) 从结果集中抓取所有记录行
mysqli_query()的返回值: (1)DML: insert delete update 失败:false 成功:true (2)DQL: select 失败:false 成功:查询结果集描述对象 |
2.SQL语句的分类
(1)DDL: Data Define Language,数据定义语言——定义列
DROP CREATE ALTER TRUNCATE
(2)DML: Data Manipulate Language,数据操作语言——操作行
INSERT DELETE UPDATE
(3)DQL: Data Query Language,数据查询语言
SELECT
(4)DCL: Data Control Language,数据控制语言——控制用户权限
GRANT REVOKE
3.完整的功能点演示:
基于单表的CRUD操作
Create Retrieve Update Delete 增删改查
4.理论学习:HTTP协议
学习HTTP协议有两个目标:
(1)调试AJAX应用中“看不见摸不着”的错误!
(2)对网站进行访问优化——面试题!
5.URL地址
URL:Unified Resource Locator,统一的资源定位符
URN:Unified Resource Naming,统一的资源命名符
URI:Unified Resource Idenfier,统一的资源识别符
URI = URL + URN
URL: http://tmooc.cn/logo.png">
URN: mailto:[email protected]">
一个URL地址最完整的格式:
练习:记忆常见协议的默认端口号
6.HTTP协议概述
Hyper Text Transfer Protocol,超文本传输协议,用于在浏览器和Web服务器之间传输超文本网页,如HTML、CSS、JS、图片...;
HTTP/0.9 1991年,有设计缺陷
HTTP/1.0 1996年,第一个稳定正式颁布 RFC-1945
HTTP/1.1 1999年,目前通用版本 RFC-2616
Request For Comment 意见征求稿
面试题:HTTP/1.0到HTTP/1.1有哪些改进? (1)虚拟主机:在一个Web服务器中并存多个站点 Host: tmooc.cn (2)持久连接:一次请求完成后,不要马上断开连接,再保持一会儿 Connection: keep-alive (3)代理连接:客户端可以通过代理服务器间接访问目标服务器 Proxy: xxxx |
HTTP协议的具体内容,规定了如下两种消息的格式:
(1)请求消息: 客户端发给服务器的
(2)响应消息: 服务器发给客户端的
课后练习:
(1)HTML中base标签的含义是什么?
(2)阶段小项目:留言板
功能:
1)发表留言: 用户在一个表单中提交自己的姓名、电话、以及留言内容,点击提交按钮即可发表。
2)浏览所有留言: 可以查看到编号、姓名、电话、内容、发布时间。
3)删除某个留言: 点击某个留言右上角的X删除该留言。
编写顺序: 创建SQL->创建PHP->创建HTML
需要的文件:
1)编写SQL:tarena.sql,创建一个留言表 msg,包含留言编号mid、发布人姓名uname、联系电话phone、发布时间pubTime、留言内容content
2)编写PHP: msg_add.php,接收客户端提交的uname、phone、pubTime、content,添加到数据库中
3)编写HTML:msg_add.html,提供一个表单,辅助用户提交一条新的留言
4)编写PHP:msg_select.php,在一个DIV列表中显示出所有的留言
5)编写PHP:msg_delete.php,接收客户端提交的mid,从数据库中删除该留言
6)修改PHP:msg_select.php,为“删除”超链接添加事件监听,点击后,删除该留言
挑战性需求:点击“删除”先弹出一个确认框,如果用户选择“是”,才真正跳转到删除页面,否则不跳转。
复习:
基于单表的CRUD操作:
$cid = $_REQUEST['cid'];
$conn = mysqli_connect();
$sql = "DDL/DML/DQL";
$result = mysqli_query($conn, $sql);
//DML: false / true
//DQL: false / 结果集描述对象
$row = mysqli_fetch_row($result)
$row = mysqli_fetch_assoc($result)
$list = mysqli_fetch_all($result, MYSQLI_ASSOC)
练习:
(1)编写SQL:jd.sql,数据库名jd,表名udisk(uid, pic, uname, price, addedTime ),添加四条测试记录 <5min
(2)编写PHP:udisk_add.php,接收客户端提交的pic, uname, price,添加到数据库 提示: PHP函数time()返回系统时间
(3)编写HTML:udisk_add.html,提供一个表单,实现U盘添加
(4)编写PHP:udisk_select.php,在DIV列表中显示出所有的U盘
(5)编写PHP:udisk_delete.php,接收客户端提交的uid,实现记录删除
(6)修改PHP:udisk_select.php,每个U盘右上角添加删除标记,点击后提交给udisk_delete.php,实现删除
今日目标:
(1)HTTP协议详解 —— 重点
1.补充:PHP常用函数
require('x.php') 在当前位置包含指定文件中的内容
2.HTTP协议
超文本传输协议,用于规定客户端浏览器和Web服务器传输数据的格式。HTTP/1.1 - RFC2616
HTTP协议规定两种消息的格式:
(1)请求消息(request):客户端发给服务器的消息
(2)响应消息(response):服务器发给客户端的消息
午间练习:翻译请求消息/响应消息中不认识的单词!!
面试题:常见的HTTP请求方法有哪些?各表示客户端的何种意图? GET/POST/PUT/DELETE/HEAD/CONNECT/TRACE/OPTIONS |
GET请求和POST请求的比较 |
||
|
GET |
POST |
如何发起 |
浏览器中输入URL回车、超链接跳转、JS跳转、SRC/HREF属性请求、GET方式提交表单、AJAX-GET |
POST方式提交表单、AJAX-POST |
请求数据的位置 |
追加在URI后,作为查询字符串,以?开头 |
放在请求主体中 |
请求数据的类型 |
只能是文本字符 |
可以是任意类型,如包含图片、视频等 |
能否用于上传文件 |
否 |
能 |
请求数据长度限制 |
有,浏览器/服务器对请求URI长度有限制(如1KB、4KB等) |
请求主体没有长度限制! |
请求数据需编码? |
需要!一个UTF-8汉字编码为9个字节 |
需要!一个UTF-8汉字编码为9个字节 |
表达的语义 |
表客户端想获取 |
表客户端想传递 |
实现了国际化的网页: internationalization I18N
今日重点:
(1)请求消息中的请求方法——八种
(2)响应消息中的响应状态码——五类
(3)请求消息主体的内容类型 和 响应消息主体的内容类型 区别
3.如何精准的描述一段数据的内容类型
不要使用后缀名!!—— 太杂乱、不可靠
.html、.xhtml、.htm
.jpg、.jpeg
.mp3、.mpeg3
....
可以借鉴MIME中定义的文件类型名称:
text/html
text/css
application/javascript
...
MIME: (Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。 |
4.如何修改响应消息的头部
(1)修改Web服务器的配置文件
比较复杂,有些情况下无法修改,如新浪云服务器
(2)若响应文件是HTML,则可以声明
仅适用于HTML文件,且只是“等价物”,并非真正的响应头部
(3)使用动态语言代码来控制响应消息头部
如PHP: //设置一个响应消息头部
header('Cache-Control: no-cache');
header('Content-Type: image/png');
5.面试题:根据HTTP协议的知识进行网站访问优化 有哪些方案?
(1)域名解析
尽可能减少域名解析次数——减少跨站外部资源的引用
(2)创建连接
努力减少连接创建次数——启用持久连接避免重复连接
(3)发送请求
尽力减少请求次数——合理设置缓存、资源合并
(4)等待响应
提高服务器端运行速度——提高数据运算及查询速度
(5)接收响应
尽可能减小响应数据长度——启用压缩
课下练习:
(1)百度:如何用PHP接收客户端上传的文件。
(2)实现完整的“用户管理系统”
主要功能:
(1)新用户注册
(2)用户登录
(3)浏览所有用户
(4)用户删除
实现步骤:
(1)编写SQL:jd.sql,表jd_user( uid, uname, upwd, headPic, regTime, loginCount )
(2)编写PHP:user_add.php,接收客户端提交的uname, upwd, headPic,把新用户信息添加到数据库,新用户的注册时间就是服务器当前系统时间,登录次数默认为0
(3)编写HTML: user_add.html,提供注册表单,辅助用户提交注册信息,提交给服务器端PHP页面实现用户注册
(4)编写PHP:user_login.php,接收客户端提交的uname和upwd,验证用户名和密码是否正确,若正确,则修改登录次数实现+1,向客户端返回“登录成功”;否则向客户端返回“用户名或密码错误”
SELECT * FROM jd_user WHERE uname='?' AND upwd='?'
UPDATE jd_user SET loginCount=loginCount+1 WHERE uid=?
(5)编写HTML:user_login.html, 提供登录表单,辅助用户提交登录信息,提交给服务器端PHP页面实现用户登录
(6)编写PHP:user_select.php,在TABLE中列出所有的用户信息
(7)编写PHP:user_delete.php,接收客户端提交的uid,从数据库中删除指定的用户
(8)修改PHP:user_select.php,在TABLE中添加“操作”列,为每个用户添加一个“删除”按钮,点击后实现用户删除
复习:
基于单表的CRUD操作:
$cid = $_REQUEST['cid'];
$conn = mysqli_connect();
$sql = "DDL/DML/DQL";
$result = mysqli_query($conn, $sql);
//DML: false / true
//DQL: false / 结果集描述对象
$row = mysqli_fetch_row($result)
$row = mysqli_fetch_assoc($result)
$list = mysqli_fetch_all($result, MYSQLI_ASSOC)
练习:
(1)编写SQL:jd.sql,数据库名jd,表名udisk(uid, pic, uname, price, addedTime ),添加四条测试记录 <5min
(2)编写PHP:udisk_add.php,接收客户端提交的pic, uname, price,添加到数据库 提示: PHP函数time()返回系统时间
(3)编写HTML:udisk_add.html,提供一个表单,实现U盘添加
(4)编写PHP:udisk_select.php,在DIV列表中显示出所有的U盘
(5)编写PHP:udisk_delete.php,接收客户端提交的uid,实现记录删除
(6)修改PHP:udisk_select.php,每个U盘右上角添加删除标记,点击后提交给udisk_delete.php,实现删除
今日目标:
(1)HTTP协议详解 —— 重点
1.补充:PHP常用函数
require('x.php') 在当前位置包含指定文件中的内容
2.HTTP协议
超文本传输协议,用于规定客户端浏览器和Web服务器传输数据的格式。HTTP/1.1 - RFC2616
HTTP协议规定两种消息的格式:
(1)请求消息(request):客户端发给服务器的消息
(2)响应消息(response):服务器发给客户端的消息
午间练习:翻译请求消息/响应消息中不认识的单词!!
面试题:常见的HTTP请求方法有哪些?各表示客户端的何种意图? GET/POST/PUT/DELETE/HEAD/CONNECT/TRACE/OPTIONS |
GET请求和POST请求的比较 |
||
|
GET |
POST |
如何发起 |
浏览器中输入URL回车、超链接跳转、JS跳转、SRC/HREF属性请求、GET方式提交表单、AJAX-GET |
POST方式提交表单、AJAX-POST |
请求数据的位置 |
追加在URI后,作为查询字符串,以?开头 |
放在请求主体中 |
请求数据的类型 |
只能是文本字符 |
可以是任意类型,如包含图片、视频等 |
能否用于上传文件 |
否 |
能 |
请求数据长度限制 |
有,浏览器/服务器对请求URI长度有限制(如1KB、4KB等) |
请求主体没有长度限制! |
请求数据需编码? |
需要!一个UTF-8汉字编码为9个字节 |
需要!一个UTF-8汉字编码为9个字节 |
表达的语义 |
表客户端想获取 |
表客户端想传递 |
实现了国际化的网页: internationalization I18N
今日重点:
(1)请求消息中的请求方法——八种
(2)响应消息中的响应状态码——五类
(3)请求消息主体的内容类型 和 响应消息主体的内容类型 区别
3.如何精准的描述一段数据的内容类型
不要使用后缀名!!—— 太杂乱、不可靠
.html、.xhtml、.htm
.jpg、.jpeg
.mp3、.mpeg3
....
可以借鉴MIME中定义的文件类型名称:
text/html
text/css
application/javascript
...
MIME: (Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。 |
4.如何修改响应消息的头部
(1)修改Web服务器的配置文件
比较复杂,有些情况下无法修改,如新浪云服务器
(2)若响应文件是HTML,则可以声明
仅适用于HTML文件,且只是“等价物”,并非真正的响应头部
(3)使用动态语言代码来控制响应消息头部
如PHP: //设置一个响应消息头部
header('Cache-Control: no-cache');
header('Content-Type: image/png');
5.面试题:根据HTTP协议的知识进行网站访问优化 有哪些方案?
(1)域名解析
尽可能减少域名解析次数——减少跨站外部资源的引用
(2)创建连接
努力减少连接创建次数——启用持久连接避免重复连接
(3)发送请求
尽力减少请求次数——合理设置缓存、资源合并
(4)等待响应
提高服务器端运行速度——提高数据运算及查询速度
(5)接收响应
尽可能减小响应数据长度——启用压缩
课下练习:
(1)百度:如何用PHP接收客户端上传的文件。
(2)实现完整的“用户管理系统”
主要功能:
(1)新用户注册
(2)用户登录
(3)浏览所有用户
(4)用户删除
实现步骤:
(1)编写SQL:jd.sql,表jd_user( uid, uname, upwd, headPic, regTime, loginCount )
(2)编写PHP:user_add.php,接收客户端提交的uname, upwd, headPic,把新用户信息添加到数据库,新用户的注册时间就是服务器当前系统时间,登录次数默认为0
(3)编写HTML: user_add.html,提供注册表单,辅助用户提交注册信息,提交给服务器端PHP页面实现用户注册
(4)编写PHP:user_login.php,接收客户端提交的uname和upwd,验证用户名和密码是否正确,若正确,则修改登录次数实现+1,向客户端返回“登录成功”;否则向客户端返回“用户名或密码错误”
SELECT * FROM jd_user WHERE uname='?' AND upwd='?'
UPDATE jd_user SET loginCount=loginCount+1 WHERE uid=?
(5)编写HTML:user_login.html, 提供登录表单,辅助用户提交登录信息,提交给服务器端PHP页面实现用户登录
(6)编写PHP:user_select.php,在TABLE中列出所有的用户信息
(7)编写PHP:user_delete.php,接收客户端提交的uid,从数据库中删除指定的用户
(8)修改PHP:user_select.php,在TABLE中添加“操作”列,为每个用户添加一个“删除”按钮,点击后实现用户删除
复习:
AJAX:异步JS和XML,涉及到HTML、CSS、JS、DOM、HTTP、XML、JSON等。目标:无刷新无提交情况下实现页面内容局部更新,提高浏览体验。
使用XHR发起异步请求步骤:
(1)创建XHR
(2)监听XHR的状态改变 0 1 2 3 4
(3)连接到Web服务器
(4)发送请求消息
练习:dangdang的后台书籍录入系统——不跳转
(1)编写SQL:dangdang.sql,表book( bid, bname, price, pic ),试着插入几行记录
(2)编写PHP:book_add.php,接收客户端提交的bname, price, pic,插入到数据库中,成功则返回succ,失败则返回err。记得同步请求测试一下
(3)编写HTML:book_add.html,没有表单,只有几个输入框,一个button按钮,单击后收集用户的输入,发起异步请求,提交给服务器
今日目标:
(1)复习XHR发起两种请求
(2)学习XHR接收五种响应 —— 重点
1.使用XHR发起两种请求之一——GET
//1 var xhr = new XMLHttpRequest();
//2 xhr.onreadystatechange = function(){}
//3 xhr.open('GET', 'x.php?k=v&k=v', true)
//4 xhr.send(null);
2.使用XHR发起两种请求之二——POST
//1 var xhr = new XMLHttpRequest();
//2 xhr.onreadystatechange = function(){}
//3 xhr.open('POST', 'x.php', true)
//3.5 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
//4 xhr.send('k=v&k=v')
3.使用XHR接收五种响应——text/plain
服务器端:
header('Content-Type: text/plain');
echo 'succ';
客户端:
if( xhr.responseText==='succ'){ ... }
案例演示:异步添加新的书籍信息
4.使用XHR接收五种响应——text/html
注意:AJAX应用中服务器返回的不是完整的HTML文档,而只是HTMP标签组成的片段
服务器端:
header(' Content-Type: text/html;charset=UTF-8 ');
echo '
客户端:
ul.innerHTML = xhr.responseText;
案例演示:搜索建议
实现顺序:
(1)编写SQL:dangdang.sql,表book(....)
(2)编写PHP:book_search.php,接收客户端提交的书名关键字kw,执行查询,返回所有包含该关键字的书名,以LI片段格式
(3)编写HTML:book_search.html,包含一个输入框,只要用户输入了文本,下方立即显示出一个包含该文本的搜索建议
input.onkeyup = function(){ var kw = this.value; }
扩展SQL语句——如何进行模糊查询 SELECT * FROM book WHERE bname='指南'; //精准匹配 SELECT * FROM book WHERE bname LIKE '指南'; //精准匹配 |
SELECT * FROM book WHERE bname LIKE '%指南%'; //%匹配任意多个任意字符——模糊匹配 |
5.使用XHR接收五种响应——application/javascript
注意:JavaScript代码在PHP解释器看来就是普通的字符串而已;
服务器端:
header(' Content-Type: application/javascript');
echo 'alert(123);document.body.appendChild(...)';
客户端:
eval( xhr.responseText ) //客户端必须使用eval来执行JS字符串
案例演示:实现了国际化(i18n)的欢迎消息
(1)编写PHP:i18n.php,解析客户端请求消息头部,获取当前客户端的首选语言,根据语言的不同,返回不同形式的欢迎消息,如alert('你好'); 或 console.log('こんにちは'); 或 var s = document.createElement('span'); s.innerHTML = 'Hello'; document.body.append(s);
(2)编写HTML,i18n.html,一个按钮“获取欢迎消息”,点击后发起异步的GET请求,获得响应消息后,执行出来。
服务器如何返回批量的复合数据给客户端? 复合数据:一个数据有多个属性 批量复合数据:有多个复合数据 —— 二维数组 |
|||||||||
方式1:用text/plain格式 101#三星#35.5#1.jpg@102#闪迪#34.5#2.jpg@金士顿#... 好处:简单 不足:不易读取、很容易出错 |
|||||||||
方式2:用text/html格式
好处:情形,方便使用 tbody.innerHTML = xhr.responseText 不足:把数据和格式混在一起,限制了数据的应用场合 |
|||||||||
方式3:用application/xml格式 <productList>
productList> 好处:是纯数据,不附带任何的显示格式限制 不足:太复杂了,阅读和解析都太麻烦 |
|||||||||
方式3:用application/json格式 [ { "pid":"101", "pname":"三星", "price":35.5, "pic":"1.jpg" }, { "pid":"102", "pname":"闪迪", "price":34.5, "pic":"2.jpg" } ] 有点:简单、易于阅读,处理速度快! |
6.XML语法学习
eXtensible Markup Language,可扩展的标签语言,本身是一种字符串格式,用于描述批量复合数据,语法:
(1)所有的数据放在标签中:
<名>数据名>
<名 />
(2)整个XML字符串有且只能有一个根标签
(3)所有的标签名都可以自定义,但严格区分大小写,且开始和结束标记必须完全一样
(4)每个标签都可以自定义属性,属性必须有值,值必须用单引号/双引号括起来
(5)每个标签都可以定义任意的子标签,标签可以嵌套,但不能交叉
注意:HTML和XML的区别——面试题
HTML语法随意;XML语法严格;
HTML标签预定义好了;XML标签都是自定义的;
HTML用于描述网页的结构;XML标签用于描述数据;
7.使用XHR接收五种响应——application/xml
服务器端:
header('Content-Type: application/xml');
echo '
客户端:
//xhr.responseText //把字符串解析为DOM对象很麻烦
xhr.responseXML //DOM树的根对象
案例演示:异步加载更多数据
(1)编写SQL:dangdang.sql,表book(...)
(2)编写PHP:book_select.php,向客户端返回所有的数据,以XML字符串格式
(3)编写HTML:book_select.html,点击“加载更多”按钮时,再次请求更多的书籍信息
W3C DOM标准分为三部分: 核心DOM: 可以操作任意的DOM树,如getElementById()、querySelector()、getAttribute().... HTML DOM: XML DOM: |
8.JSON字符串格式的语法
JSON(JavaScript Object Notation) 是一种轻量级的字符串数据格式。 易于人阅读和编写;同时也易于机器解析和生成;在Web编程领域可以取代XML字符串格式!
(1)数据分为两种: [ ] { }
(2)整个字符串要么是一个数组、要么是一个对象
(3)数组中可以包含各种: 数字、boolean、字符串、null、[]、 {}
(4)对象中可以包含多个键值对,键必须用双引号,值若是字符串也必须用双引号
9.使用XHR接收五种响应——application/json
服务器端:
header('Content-Type: application/json;charset=UTF-8');
$arr = ....;
$str = json_encode($arr); //把PHP数组转换为JSON字符串
echo $str;
客户端:
JSON.parse( xhr.responseText ); //把JSON字符串解析为JS对象
=============================
10.ES6中新的字符串
var str = `
phone=${p}&pwd=${w}
`;
反引号字符串可以换行;可以包含${}的变量或表单式。
课下练习:
功能要求:
(1)编写SQL,数据库名: tarena,员工信息表emp(eid,ename,pic, salary,deptID),保存多个员工的信息;
(2)编写PHP,emp_select.php,根据客户端提交的部门编号(deptID),返回该部门下的员工信息;
(3)编写HTML,emp_select.html,下拉框中选择不同的部门,则下方的员工列表显示出该部门的员工信息;
select.onchange = function(){ this.value }
(4)点击“删除”,发起异步请求删除该员工信息,服务器返回删除成功信息后,前端页面将表格中的当前行删除。
复习:
AJAX:向服务器发起异步HTTP请求,接收处理返回的响应消息,目标是实现页面在无刷新无提交情况下页面内容的局部更新。
使用AJAX发起两种请求消息:
GET://1 //2 //3 //4
POST : //1 //2 //3 //3.5 //4
使用AJAX接收五种响应消息:
(1)text/plain
服务器端:
header('Content-Type: text/plain');
echo 'succ';
客户端:
if(xhr.responseText==='succ'){ ... }
(2)text/html
服务器端:
header('Content-Type: text/html');
echo " ";$data
客户端:
tbody.innerHTML = xhr.responseText
(3)application/javascript
服务器端:
header('Content-Type: application/javascript');
echo "alert($data); f1(); f2($data)";
客户端:
eval( xhr.responseText )
(4)application/xml
服务器端:
header('Content-Type: application/xml');
echo "
客户端:
var document = xhr.responseXML
(5)application/json
服务器端:
header('Content-Type: application/json');
//echo "[ {"bname":"","price":35.5},{} ]";
$list = ...;
echo json_encode($list);
客户端:
var obj = JSON.parse( xhr.responseText )
练习: 实现学生查询系统
(1)编写SQL:qinghua.sql,表qh_class( cid, cname, count ),插入三个班级(10/20/30);qh_student(sid, sname, score, classId),插入八九行记录
(2)编写PHP:class_select.php,向客户端输出所有的班级信息,以JSON格式: [{},{},{}]
(3)编写HTML:qinghua.html,页面加载完成(window.onload)后,异步请求,获取所有的班级信息,填充在一个select中
(4)编写PHP:student_select.php,接收客户端提交的cid,返回指定班级中的学生数据,以JSON格式: [{},{},{}]
(5)修改HTML:qinghua.html,为select做事件绑定,监听选项改变,异步请求选定班级中的学生,显示在table中
今日目标:
(1)使用jQuery的AJAX封装函数——六个
1.使用jQuery的AJAX封装函数之一——load()
使用方法:
$('选择器').load(URL, [请求数据], [成功后的回调函数])
$('ul').load('search_suggest.php');
含义说明:
向指定的URL发起异步请求;若有请求数据,就是POST请求,否则就是GET请求;获取服务器端返回HTML片段响应,设置为当前选定元素的innerHTML。
使用限制:
(1)服务器返回的必需是HTML片段;
(2)服务器端返回的数据会替换已有数据!
案例演示: 异步加载多个页面完全一样的页头/页尾
(1)编写header.php,只含有页头中的DIV片段
(2)编写footer.php,只含有页尾中的DIV片段
(3)编写jdindex.php,内容:
待页面加载完后,异步请求页头,放在#header中
待页面加载完后,异步请求页尾,放在#footer中
2.使用jQuery的AJAX封装函数之二——$.get()
使用方法:
$.get(URL, [请求数据], 响应成功后的回调函数)
$.get('delete.php', 'sid=8', function(txt){ if(txt==='succ'){} })
$.get('delete.php', {sid:8}, function(txt, msg, xhr){ if(txt==='succ'){} })
含义作用:
向指定的URL发起异步的GET请求,把请求数据追加在URL的后面;服务器给出了成功的响应会自动调用第三个参数——doResponse。
提示:$.get会根据服务器端返回的响应消息内容类型自动决定如何处理,如applicatoin/json,会自动调用JSON.parse(xhr.responseText)进行解析!
案例演示:实现异步的学生记录的删除
案例演示:异步级联下拉列表 $.get()
(1)编写SQL:qinghua.sql,产品类别表 qh_type( tid, tname ),插入三行数据(10-相机、20-洗衣机、30-手机),生产厂家表qh_producer( pid, pname, typeId ),插入若干记录;产品型号表 qh_model( mid, mname, producerId )
(2)编写PHP:type_select.php,向客户端返回所有的产品类型,以JSON格式
(3)编写PHP:producer_select.php,根据客户端提交的typeId,向客户端返回该类型所有的厂家,以JSON格式
(4)编写PHP:model_select.php,根据客户端提交的producerId,向客户端返回该厂家生产的所有型号,以JSON格式
(5)编写HTML,product.html,
当页面加载完成后,异步请求所有的“产品类型”;
当产品类型选项发生改变后,异步请求对应的“生产厂家”;
当生产厂家选项发生改变后,异步请求该厂家的“产品型号”
3.使用jQuery的AJAX封装函数之三——$.post()
使用方法:
$.post(URL, 请求数据, 响应成功后的回调函数)
含义作用:
向指定的URL发起异步的POST请求,把请求数据放置在请求主体——无需手写3.5步;服务器给出了成功的响应会自动调用第三个参数——doResponse。
提示:$.post会根据服务器端返回的响应消息内容类型自动决定如何处理,如applicatoin/json,会自动调用JSON.parse(xhr.responseText)进行解析!
案例演示:实现异步的用户注册
(1)编写SQL:qinghua.sql,用户信息表 qh_user(uid, uname,upwd)
(2)编写PHP:user_add.php,接收客户端提交的uname和upwd,返回succ或err
(3)编写HTML:user_add.html,没有表单,只有两个输入域+BUTTON按钮,点击后异步提交给服务器 $.post(url, {uname:xx, upwd:xx}, fn)
4.使用jQuery的AJAX封装函数之四——$.getScript()——了解
使用方法:
$.getScript(URL, [请求数据], [响应成功后的回调函数])
$.getScript('x.php')
含义作用:
向指定的URL发起异步的GET请求,把请求数据放置在url后面;服务器给出了成功的响应会自动执行eval( xhr.responseText )。
使用限制:
要求服务器必须返回application/javascript!即使不是,也会强制调用eval(xhr.responseText)进行执行!而$.get()可以实现同样的功能,却可以根据服务器端的响应头来决定是否调用eval()
5.使用jQuery的AJAX封装函数之五——$.getJSON()——了解
使用方法:
$.getJSON(URL, [请求数据], 响应成功后的回调函数)
$.getJSON('x.php', function(obj){})
含义作用:
向指定的URL发起异步的GET请求,把请求数据放置在url后面;服务器给出了成功的响应会自动执行JSON.parse( xhr.responseText )。
使用限制:
要求服务器必须返回application/json!即使不是,也会强制调用JSON.parse(xhr.responseText)进行执行!而$.get()可以实现同样的功能,却可以根据服务器端的响应头来决定是否调用JSON.parse()
上述五个函数的通病:只能处理成功的响应消息!如果服务器端返回了错误的响应消息(如404)上述五个函数不会有任何的提示——没有相关的回调函数!
面试题:如何使用jQuery的AJAX相关函数,监听失败的响应消息??——使用万能AJAX封装函数:$.ajax |
6.使用jQuery的AJAX封装函数之六——$.ajax()——重点
使用方法:
$.ajax( {
type: 'GET', //POST/PUT/DELETE...
url: 'x.php',
data: 'k=v&k=v', //{k:v, k:v}
beforeSend: fn, //在请求发送前的回调
success: fn, //响应成功后的回调
error: fn, //响应失败后的回调
complete: fn //响应完成后(不论成败)的回调
} )
成功的调用: beforeSend() => success() => complete()
失败的调用: beforeSend() => error() => complete()
对应于原生AJAX: //1 var xhr = new XMLHttpRequest(); //2 xhr.onreadystatechange = function(){ if(xhr.readyState===4){ if(xhr.status===200){ success(); }else { error(); } complete() } } //3 xhr.open() beforeSend(); //4 xhr.send() |
课后练习:仿beijing.huimaiche.com中的车辆展示
(1)编写SQL,创建huimaiche.sql,保存车辆数据(cid,cname,price,count,type(lt8/lt15/lt30/suv))
(2)编写PHP,创建car_list.php,根据客户端提交的车辆类别,返回该类别下所有汽车,以JSON格式
(3)编写HTML,创建car_list.html,用户鼠标悬停在不同的车辆类别上,异步请求该类别下所有的汽车
(4)编写PHP,创建car_select.php,根据客户端提交的cid,向客户端输出该车辆的所有信息,以JSON格式
(5)修改car_list.html,当用户点击某个车辆的图片时,在下方显示出该车辆的全部信息
复习:
见思维导图
练习:学生按分数级别显示
(1)编写SQL:tarena.sql,表student(sid, sname, pic, scoreGrade(A-B-C-D)),插入12条记录
(2)编写PHP:student_select.php,根据客户端请求分数级别,返回该级别下有哪些学生,以JSON格式
(3)编写HTML:student.select.html,页头提供ABCD四个级别,鼠标悬停在某个级别上,立即异步请求该级别有哪些学生
今日目标:
(1)PPT上的小知识点拾遗
(2)AJAX阶段项目 —— 重点
1. JS中如何处理JSON字符串
把JSON格式的字符串解析为JS对象:
var str = '{"ename":"Tom", "age":20}';
var obj = JSON.parse(str); //方法1
var obj = eval( '('+str+')' ); //方法2,不推荐使用
把JS对象编码为JSON字符串:
var obj = {ename:'Tom', age: 20};
var str = JSON.stringify(obj);
-ify: 使变为..., sheepify stoneify frogify
=================================
PHP中把数组编码为JSON字符串:
$list = [{},{},{}];
$str = json_encode( $list );
PHP中JSON字符串解析为PHP数组/对象:
$str = '{"ename":"Tom", "age":20}';
$obj = json_decode( $str );
2.面试题:跨域请求和JSONP
Cross Domain Request:从一个资源请求另一个资源,二者所在的请求地址不同,域名不同、端口号不同、请求协议不同。
http://www.tmooc.cn/list.html
http://www.tedu.cn/student_select.php
提示:localhost和127.0.0.1也算跨域!
浏览器允许跨域请求的情形:
IMG、LINK、SCRIPT、IFRAME ...
浏览器禁止跨域请求的情形:
XHR —— 浏览器处于安全考虑,禁用了XHR的跨域请求(其实服务器给出了响应消息,但浏览器不让使用)
面试题:我们公司项目很大,页面很多,出于性能考虑,把静态资源(html等)放在http://static.tmooc.cn服务器上了,把动态资源(php)放在http://dynamic.tmooc.cn服务器上了,如何让一个x.html异步请求x.php呢? |
如何解决浏览器的XHR跨域请求限制 —— 八种方案:
(1)
(2)
(3)
(4)
(5)
(6)
(7) 修改响应消息头部,添加Access-Control-Allow-Origin头部
(8) 使用JSONP——非常巧妙
JSON: JavaScript Object Notation,是一种字符串数据格式(羊肉)。
JSONP:JSON with Padding,填充式JSON,与JSON完全两码事,是一种使用JSON数据的方式(把羊肉红烧)。意思是在JSON字符串左右添加函数名: doResponse( {"ename":"Tom", "age":20} );
JSONP是专用于解决XHR跨域限制一种手段。基本原理:使用动态创建的一个SCRIPT标签代替XHR发起异步请求,要求服务器必须返回application/javascript,立即在客户端执行——要执行的函数本体在客户端浏览器中声明。
面试题:jQuery中如何使用JSONP发起异步请求:
(1) $.getJSON()
用途1:使用XHR发起异步请求(不能跨域)
$.getJSON('x.php', doResponse)
用途2:使用JSONP发起跨域异步请求
$.getJSON('http://跨域地址/x.php?callback=?', doResponse)
(2) $.ajax()
用途1:使用XHR发起异步请求(不能跨域)
$.ajax({ })
用途2:使用JSONP发起跨域异步请求
$.ajax({ dataType: 'jsonp' })
3.AJAX阶段项目 —— 京东购物车
功能点描述
(1)异步的用户登录
(2)异步的显示商品列表,实现分页显示
(3)异步的添加到“我的购物车”
(4)查看“我的购物车”
(5)异步的修改“我的购物车”
项目标准: 根据注释,大家在前面写,我在后面提示——项目代码必须有自己的思路!
实现步骤: SQL => PHP => HTML/JS
(1)编写SQL:jd.sql,数据库名jd,
创建表:jd_user(uid, uname, upwd),插入2行记录:
10 qiangdong 123456
20 naicha 456789
创建表:jd_product(pid, pname, price, pic),插入36行记录;
创建表:jd_cart( cid, userId ),插入一行记录:
101 10
创建表:jd_cart_detail(did, cartId, productId, count),插入如下的3行测试记录:
1 101 15 3
2 101 18 1
3 101 21 2
(2)编写PHP:data/header.php,包含页头必需的HTML片段(第一阶段项目中寻找)——不是完整的HTML!
(3)编写PHP:data/footer.php,包含页尾必需的HTML片段(第一阶段项目中寻找)——不是完整的HTML!
(4)编写HTML:productlist.html,待页面加载完成,异步加载页头和页尾。
$('#header').load('data/header.php')
注意:控制台不能有404错误!
(5)编写PHP:user_login.php,接收客户端提交的uname和upwd,执行数据库验证,返回 {"code":1, "uname":"qiangdong", "uid":10} 或 {"code":2, "msg":"用户名或密码错误" }
$str = "{\"code\":1, \"uname\":\"$uname\"}"; echo $str;
$arr = ['code'=>1, 'uname'=>$uname]; echo json_encode($arr);
-------------------文华的进度线---------------------
(6)修改HTML:productlist.html,默认显示出登录对话框,异步登录验证,失败则提示错误消息,成功则清除掉对话框,显示“欢迎回来:xxxx”
(7)编写PHP:product_select.php,向客户端输出所有的产品信息,以JSON格式:[{},{},{},....]
(8)修改HTML: productlist.html,页面加载完后,异步请求所有的产品
(9)编写PHP:cart_product_add.php,接收客户端提交uid、pid,添加入购物车详情表,若已有该商品,则购买数量+1 —— 需要执行多条SQL语句,有挑战性!
4.JS和CSS加载外部资源的路径问题
JS是运行于HTML网页中,JS中请求的资源的路径使用相对于HTML文件的路径;
CSS是独立被浏览器解释,CSS中使用外部资源(如图片)路径使用相对于CSS文件的路径;
1.AJAX阶段项目——京东购物车
功能点描述
(1)异步的用户登录
(2)异步的显示商品列表,实现分页显示
(3)异步的添加到“我的购物车”
(4)查看“我的购物车”
(5)异步的修改“我的购物车”
所用技术:
MySQL、PHP、HTTP、AJAX、jQuery、Cookie
实现步骤: SQL => PHP => HTML/JS
(1)编写SQL:jd.sql,数据库名jd,
创建表:jd_user(uid, uname, upwd)
创建表:jd_product(pid, pname, price, pic)
创建表:jd_cart( cid, userId )
创建表:jd_cart_detail(did, cartId, productId, count)
(2)编写PHP:data/header.php,包含页头必需的HTML片段
(3)编写PHP:data/footer.php,包含页尾必需的HTML片段
(4)编写HTML:productlist.html,待页面加载完成,异步加载页头和页尾。
(5)编写PHP:user_login.php,接收客户端提交的uname和upwd,执行数据库验证,返回 {"code":1, "uname":"qiangdong", "uid":10} 或 {"code":2, "msg":"用户名或密码错误" }
(6)修改HTML:productlist.html,默认显示出登录对话框,异步登录验证,失败则提示错误消息,成功则清除掉对话框,显示“欢迎回来:xxxx”
(7)编写PHP:product_select.php,向客户端输出所有的产品信息,以JSON格式:[{},{},{},....]
(8)修改HTML: productlist.html,页面加载完后,异步请求产品;分页显示
(9)编写PHP:cart_product_add.php,接收客户端提交uid、pid,添加入购物车详情表,若已有该商品,则购买数量+1 —— 需要执行多条SQL语句
SQL1:根据用户编号查询出购物车编号
SQL2:若没有购物车编号则创建一个购物车,得到购物车编号
SQL3:根据购物车编号和产品编号查询是否已买过该商品
SQL4:已购买过则购买数量+1
SQL5:未购买过则添加购买记录,数量为1
(10)修改HTML:productlist.html,点击每个商品下“添加到购物车”,异步把uid和pid提交给服务器,实现购物车添加,弹出成功提示消息,提示用户该商品已购物的数量。
(11)用户点击“查看我的购物车”,把loginUid和loginUname保存到Cookie中,跳转到shoppingcart.html
(12)修改shoppingcart.html,页面加载完成,从Cookie中读取loginUid和loginUname
(13)修改shoppingcart.html,页面加载完成,异步请求页头和页尾页面
(14)编写PHP,cart_detail_select.php,接收客户端提交的uid,查询出该用户购物车中所有的商品,返回:[{},{},...{}]
(15)修改HTML,shoppingcart.html,待页面加载完后,异步请求当前用户的购物车商品列表,显示在TABLE中
-------------------文华的进度线--------------------
(16)编写PHP:cart_detail_update.php,接收客户端提交的did和count,执行UPDATE,修改详情条目的购买数量,返回{"code":1,"count": 3}
(17)修改HTML,shoppingcart.html,为+和-按钮绑定事件监听,修改同级的input的value,异步提交给服务器
(18)编写PHP:cart_detail_delete.php,接收客户端提交的did,执行DELETE,删除该详情条目返回{"code":1 }
(19)修改HTML,shoppingcart.html,为“删除”按钮绑定事件监听,异步提交给服务器
2.表单序列化
$('#formId').serialize( );
jQuery中提供的表单序列化函数,可以把选定的表单中所有带name属性的输入域连同值转换为k=v形式,全部使用&符号拼接在一起,组成一个大的字符串,用于异步请求数据提交。
3.Web项目中的分页查询 —— 难点 & 重点
当一个页面需要呈现的数据很多时,不可能一次性全部显示,必须使用分页显示:
初始时显示第1页,用户点击某个页号,异步请求对应页中的内容。
分页查询客户端提交的请求消息形如:
GET /select.php?pageNum=3 HTTP/1.1
分页查询服务器返回的响应消息形如:
{
recordCount: 36,//满足条件的记录的总数
pageSize: 8,//页面大小,每页最多显示的记录数
pageCount: 5, //总的页数
pageNum: 3,//当前显示的页号
data: [ {},{}...{} ]//当前页中的数据
}
(1)MySQL如何查询出符合条件的总的记录数量
SELECT COUNT(*) FROM jd_product WHERE...;
查询结果集中有一行一列的数据
(2)PHP如何计算页面的总数量:
ceil( recordCount / pageSize ) //上取整函数
(3)MySQL如何实现查询指定页面中的记录
提示:不同的数据库实现分页查询的SQL各不相同!
SELECT * FROM jd_product WHERE ... LIMIT start, count;
LIMIT: 限制,结果集中从哪一行开始获取数据(从0开始),最多要多少行。
第1页: LIMIT 0, 8 01234567
第2页: LIMIT 8, 8 89101112131415
第3页: LIMIT 16, 8
第4页: LIMIT 24, 8
第5页: LIMIT 32, 8
第pageNum页:
LIMIT (pageNum-1)*pageSize, pageSize
1 2 3
1 2 3 4
1 2 3 4 5
2 3 4 5
3 4 5
4.关系型数据库中两个表间的关系——数据设计理论
(1)一对一关系
可以在任一表中添加引用对方表的外键列
(2)一对多关系
部门vs员工、板块vs帖子、商品vs留言、分类vs商品
只能在多方表中添加外键列,引用一方的主键
(3)多对多关系
商品vs购物车、学生vs课程、工人vs车间、员工vs项目
只能再创建一个中间表,有两个外键列,分别指向每个表的主键
5.如何访问异步加载的页头和页尾中的元素:
事件绑定: 可以委托给DOM树上已有的父元素
HTML内容操作:
$(...).load('x.php', function(){
//异步请求完成后,再处理后加载的DOM元素
})
6.SQL中的多表查询
CREATE TABLE dept( did INT, dname VARCHAR(32) );
INSERT INTO dept VALUES
(10, '研发部'),
(20,'市场部');
CREATE TABLE emp( eid INT, ename VARCHAR(32), deptId INT );
INSERT INTO emp VALUES
(1, 'Tom', 10),
(2,'Mary', 10),
(3,'John', 20);
请查询出每个员工姓名及其所在部门名称:
SELECT ename, dname FROM emp, dept; //该语句会得到一个笛卡尔积:从每个表中任取一行记录,与另一表中的每一行记录匹配,配对总可能数:m * n
SELECT ename, dname FROM emp, dept
WHERE deptId = did;
跨表查询:查询得到的结果集来自于多个表!为了避免产生笛卡尔积,必须有两个表的相等条件!