HTTP
HTTP 概述
HTTP(Hyper Text Transfer Protocol,超文本传输协议) 是浏览器与 Web 服务器之间进行数据交互时需要遵循的一种协议,用于定义浏览器与 Web 服务器之间数据交换的格式。

HTTP 的特点:
- 简单快速:客户端向服务器发送请求时,只需要传送请求方式和请求路径等简单信息。
- 灵活:HTTP 允许传输任意类型的数据。
- 无连接:限制每次连接只处理一个请求,服务器处理完客户端的请求,并收到客户端的应答后,就会断开连接,节省传输时间。
- 无状态:协议对于事物处理没有记忆能力,如果后续的处理需要使用前面请求的数据,则必须重新传递,这样可能导致每次连接发送的数据量增大,但当在服务器不需要前面的请求数据时,应答就比较快。
HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer,超文本传输安全协议)解决了 HTTP 明文传输不安全的问题,它在 HTTP 基础上通过加密和身份认证保证数据传输过程中的安全性。主要应用于对安全性要求比较高的通讯中。
HTTPS 和 HTTP 的区别:
- 安全性:HTTP 数据都是未加密的,明文传输,安全性较差,HTTPS 数据传输过程是加密的,安全性较好。
- 页面响应速度:HTTP 页面响应速度比 HTTPS 快,HTTPS 协议包含了传输加密和身份认证,比 HTTP 更耗费服务器资源。
- 端口:HTTP 默认使用 80 端口,HTTPS 默认使用 443 端口。
HTTP/1.0
基于 HTTP/1.0 版本的客户端与服务器在交互过程中需要经历 :
- 建立 TCP 连接:基于 TCP(Transmission Control Protocol,传输控制协议),由操作系统实现。
- 发送 HTTP 请求:客户端(如浏览器)按照 HTTP 规定的格式向 Web 服务器发送 HTTP 请求,Web 服务器(如 Nginx)接收到请求后按照 HTTP 解析出具体的内容进行处理。
- 回送 HTTP 响应:Web 服务器处理完成后,为了告知浏览器处理结果,再按照 HTTP 回送响应消息,从而完成整个交互过程。
- 关闭 TCP 连接:由操作系统实现。
使用 HTTP/1.0 每次建立 TCP 连接后,只能处理一个 HTTP 请求,这种通信方式对于内容越来越丰富的网页来说,效率十分低下。

HTTP/1.1
HTTP/1.1 支持持久连接,能够在一个 TCP 连接上传送多个 HTTP 请求和响应,从而避免多次建立和关闭 TCP 连接导致网页加载延时的问题。
当客户端与服务器建立连接后,客户端可以发送多个 HTTP 请求,并且在发送下一个请求时无须等待上次请求的返回结果,服务器必须按照接收请求的先后顺序依次返回响应结果,以保证客户端区分每次的响应内容,因此 HTTP/1.1 有效提高了交互效率。

请求消息
当用户通过浏览器访问网站时,浏览器会向服务器发送请求数据,这些请求数据被称为请求消息。
plaintext
POST /index.php HTTP/1.1
Host: localhost
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
a=1&b=2
请求消息包含:
- 请求行:位于请求消息的第一行,其包含请求方式、请求资源路径和 HTTP 协议版本。
- 请求头:位于请求行之后,用于向服务器传递附加消息。
- 空行:用于分隔请求头和请求体。
- 请求体:通过 POST 方式提交表单时,浏览器会将用户填写的数据放在请求体中发送。
请求头的基本参数:
| 名称 | 描述 |
|---|---|
| Accept | 客户端接受的数据类型 |
| Accept-Charset | 客户端接受的字符集 |
| Accept-Encoding | 客户端接受的数据编码格式 |
| Accept-Language | 客户端接受的语言,可以指定多个 |
| Host | 客户端想要访问的服务器主机 |
| If-Modified-Since | 客户端拥有资源的有效时间 |
| Referer | 客户端的原始资源 URI |
| User-Agent | 客户端的系统信息,包括操作系统、浏览器版本号等 |
| Cookie | 客户端需要带给服务器的数据 |
| Cache-Control | 客户端的缓存控制 |
| Connection | 请求完成后,客户端希望是保持连接还是关闭连接 |
| Content-Type | 客户端发送的请求体的数据类型 |
| Content-Length | 客户端发送的请求体的长度 |
在浏览器的开发者工具中,可以查看请求标头。

$_SERVER
超全局数组变量 $_SERVER 是一个关联数组,可以查看服务器的相关信息和 PHP 运行环境的相关信息,这些信息由 Web 服务器创建,对于不同的 Web 服务器,获取到的内容也会有所不同。
超全局数组变量 $_SERVER 中的基本参数:
| 名称 | 描述 |
|---|---|
| HTTP_HOST | 当前请求头中 Host 字段的内容 |
| HTTP_USER_AGENT | 当前请求头中 User-Agent 字段的内容 |
| HTTP_ACCEPT | 当前请求头中 Accept 字段的内容 |
| HTTP_ACCEPT_ENCODING | 当前请求头中 Accept-Encoding 字段的内容 |
| HTTP_ACCEPT_LANGUAGE | 当前请求头中 Accept-Language 字段的内容 |
| HTTP_REFERER | 当前请求头中 Referer 字段的内容 |
| SERVER_NAME | 服务器名称 |
| SERVER_ADDR | 服务器地址 |
| SERVER_PORT | 服务器端口 |
| REMOTE_ADDR | 来源地址 |
| REMOTE_PORT | 来源端口 |
| DOCUMENT_ROOT | 服务器文档根目录 |
| SERVER_ADMIN | 服务器管理员邮箱地址 |
| SCRIPT_FILENAME | 脚本文件的绝对路径 |
| SCRIPT_NAME | 脚本文件的相对路径 |
| SERVER_PROTOCOL | HTTP 版本 |
| REQUEST_METHOD | 请求方式 |
| QUERY_STRING | "?"后面的 URL 参数 |
| REQUEST_URI | 请求 URI |
| PHP_SELF | 脚本文件的相对路径 |
| REQUEST_TIME | 客户端发出请求的时间戳 |
示例:$_SERVER
入口页面(index.php):
PHP
<?php
print_r("请求头中的Host:".$_SERVER["HTTP_HOST"]."<br>");
print_r("请求头中的User-Agent:".$_SERVER["HTTP_USER_AGENT"]."<br>");
print_r("服务器名称:".$_SERVER["SERVER_NAME"]."<br>");
print_r("服务器端口:".$_SERVER["SERVER_PORT"]."<br>");
print_r("请求方式:".$_SERVER["REQUEST_METHOD"]."<br>");
示例效果:

响应消息
服务器接收到客户端发送的请求数据后,将处理后的数据返回给客户端,这些数据被称为响应消息。
plaintext
HTTP/1.1 200 OK
Date: Wed, 26 Oct 2016 01:15:33 GMT
Server: Apache/2.2.25 (Win32) mod_fcgid/2.3.6
Vary: Accept-Encoding,Cookie
Cache-Control: max-age=3, must-revalidate
Content-Length: 18327
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<html><body></body></html>
响应消息包含:
- 响应行:位于 HTTP 响应消息的第一行,用于告知客户端本次响应的状态。
- 响应头:告知浏览器本次响应的基本信息。
- 空行:用于分隔响应头和响应体。
- 响应体:服务器给浏览器返回的数据,浏览器对不同类型的响应体会有不同的处理方式。
响应头的基本参数:
| 名称 | 描述 |
|---|---|
| Server | 服务器的类型和版本信息 |
| Date | 服务器的响应时间 |
| Expires | 控制缓存的过期时间 |
| Location | 控制浏览器显示哪个页面,重定向到新的 URL |
| Accept-Ranges | 服务器是否支持分段请求,以及请求范围 |
| Content-Disposition | 服务器控制浏览器以下载方式打开文件 |
| Content-Encoding | 实体内容的编码格式 |
| Content-Length | 实体内容的长度 |
| Content-Language | 实体内容的语言和国家名 |
| Content-Type | 实体内容的类型 |
| Last-Modified | 请求文档的最后一次修改时间 |
| Transfer-Encoding | 文件传输编码 |
| Set-Cookie | 发送 Cookie 相关的信息 |
| Connection | 是否需要持久连接 |
在浏览器的开发者工具中,可以查看响应标头。

header 函数
有时开发者需要手动更改一些响应消息头,以满足网站项目的特殊需求,通过 header 函数可以自定义响应头。
示例:header 函数
入口页面(index.php):
PHP
<?php
header("Location: https://www.duox.dev");
表单
表单组成
一个完整的表单是由 form 标签和表单控件标签组成的。
form 标签的基本用法:
HTML
<form action="..." method="..." enctype="...">
<!-- ... -->
</form>
form 标签的基本属性:
| 名称 | 描述 |
|---|---|
| action | 指定接收表单数据的服务器程序的地址 |
| method | 设置表单数据的提交方式,可选 GET/POST ,默认值为 GET |
| enctype | 设置表单数据发送到服务器前对表单数据的编码方式 application/x-www-form-urlencoded:默认值,在发送表单数据前对所有字符编码 multipart/form-data:不进行字符编码,通常含有文件上传的表单使用该值 text/plain:传输普通文本,不对特殊字符编码 |
input 表单控件标签的基本用法:
HTML
<!-- 文本框 -->
<input type="text" name="user" value="test">
<!-- 密码框 -->
<input type="password" name="pwd" value="">
<!-- 文件上传域 -->
<input type="file" name="upload">
<!-- 隐藏域 -->
<input type="hidden" name="id" value="2">
<!-- 重置按钮 -->
<input type="reset" value="重置">
<!-- 提交按钮 -->
<input type="submit" value="提交">
<!-- 单选按钮 -->
<input type="radio" name="gender" value="m" checked> 男
<input type="radio" name="gender" value="w"> 女
<!-- 复选按钮 -->
<input type="checkbox" name="hobby[]" value="reading" checked> 读书
<input type="checkbox" name="hobby[]" value="running"> 跑步
textarea 表单控件标签的基本用法:
HTML
<textarea name="introduce" cols="5" rows="10">
<!-- ... -->
</textarea>
select 表单控件标签的基本用法:
HTML
<select name="area">
<option selected>--请选择--</option>
<option value="xiamen">厦门</option>
<option value="quanzhou">泉州</option>
<!-- ... -->
</select>
表单数据交互
表单数据提交后,在 PHP 中可以使用不同的超全局数组变量接收数据。
接收表单数据的基本超全局数组变量:
| 名称 | 描述 |
|---|---|
| $_GET["key"] | 接收 GET 方式提交的数据 |
| $_POST["key"] | 接收 POST 方式提交的数据 |
| $_REQUEST["key"] | 接收 GET 或 POST 方式提交的数据 |
示例:表单数据交互
入口页面(index.php):
PHP
<?php
var_dump($_REQUEST);
?>
<form method="post" action="index.php?a=param1">
<input type="text" name="b" value="param2">
<input type="submit" value="提交">
</form>
示例效果:

Cookie
Cookie 概述
Cookie 是网站为了辨别用户身份而存储在用户本地终端(浏览器)上的数据。
当用户第一次访问 Web 服务器时,服务器会返回给用户一些信息,这些信息都保存在浏览器的 Cookie 中,当用户再次访问服务器时,浏览器会在请求头中将 Cookie 数据发送给服务器。
服务器接收到浏览器的请求后,根据请求头中的 Cookie 数据,判断用户是否访问过,进而识别用户的身份。

尽管 Cookie 实现了浏览器与 Web 服务器之间的信息交互,但也存在缺点:
- Cookie 被附加在 HTTP 消息中,无形中增加了数据量。
- Cookie 在 HTTP 消息中是明文传输的,所以安全性不高,容易被窃取。
- Cookie 存储于浏览器,可以被篡改,服务器接收到数据后必须先验证数据的合法性。
- 浏览器限制 Cookie 的数量和大小,通常限制为 50 个,每个不超过 4KB,对于复杂的存储需求来说是不够用的。
Cookie 基本使用
使用 setcookie 函数可以创建或修改 Cookie。
setcookie 函数的基本用法:
PHP
setcookie(Cookie键, Cookie值, 有效时间戳, 生效路径, 生效域名, 是否需要在HTTPS传输);
任何从客户端发送的 Cookie 数据都会被自动存入到 _COOKIE 超全局数组变量中,通过 _COOKIE 变量可以获取 Cookie 数据。
$_COOKIE 超全局数组变量的基本用法:
PHP
$_COOKIE[Cookie键];
第一次使用 setcookie 函数创建 Cookie 时,_COOKIE 超全局数组变量中没有 Cookie 数据,只有当浏览器下次请求并携带 Cookie 时,才能通过 _COOKIE 超全局数组变量获取到 Cookie 数据。
示例:Cookie
入口页面(index.php):
PHP
<?php
// 设置Cookie
setcookie("userName", "多仔");
// 获取指定Cookie
echo $_COOKIE["userName"];
// 立即过期,删除Cookie
setcookie("userName", "", time() - 1);
// 获取所有Cookie
var_dump($_COOKIE);
示例效果:

Cookie 保存方式
Cookie 在浏览器中是根据域名分开保存的,每个 Cookie 都具有名字、值、域名、路径等信息,浏览器在发送 Cookie 时,不同主机和不同路径之间都是隔离的,路径可以向下继承。
setcookie 函数可以设置 Cookie 的访问路径和有效域名。
一个浏览器、一个域名下最多可以存放 Cookie 的数量、大小都会受到浏览器的限制,不同版本的浏览器限制不同,不建议在 Cookie 中存放太多的数据。
Session
Session 概述
Session 存储在服务器端,是用于实现数据跨脚本共享的会话技术,它的生命周期从用户访问页面开始,到与网站断开连接时结束,保存用户连续访问 Web 服务器时的相关数据。
Session 技术的实现依赖于 Cookie 技术。
当通过浏览器访问服务器时,服务器会设置 Cookie 给浏览器,同时服务器会创建一个 Session 文件来存储核心数据。
浏览器再次访问服务器时,服务器会根据 Cookie 数据打开对应的 Session 文件,获取存储的内容信息。

PHP 程序启动 Session 后,服务器会为每个浏览器创建一个供其独享的 Session 文件,每一个 Session 文件都具有唯一的会话 ID,用于标识不同的用户,会话 ID 分别保存在客户端和服务器端,客户端通过 Cookie 保存,服务器端则以文件的形式保存。

Session 基本使用
使用 session_start 函数可以启动 Session。
session_start 函数的基本用法:
PHP
session_start();
Session 启动后,可以使用 $_SESSION 全局数组操作 Session。
$_SESSION 全局数组的基本用法:
PHP
$_SESSION[Session键];
$_SESSION[Session键] = 值;
示例:Session
入口页面(index.php):
PHP
<?php
// 开启Session
session_start();
// 设置Session
$_SESSION["userName"] = "多仔";
// 获取Session
echo $_SESSION["userName"];
// 删除Session
unset($_SESSION["username"]);
// 清空Session
$_SESSION = [];
// 结束Session
session_destroy();
示例效果:

cURL
cURL 概述
cURL 扩展是一个基于 libcurl 库开发的扩展,其可以像浏览器一样完成与服务器的连接和通信,cURL 扩展支持多种传输协议,如 HTTP、HTTPS、FTP 等。
cURL 的基本函数:
| 名称 | 描述 |
|---|---|
| curl_init() | 初始化一个 cURL 会话 |
| curl_setopt (ch, option, $value) | 设置一个 cURL 传输选项 |
| curl_exec($ch) | 执行一个 cURL 会话 |
| curl_close($ch) | 关闭一个 cURL 会话 |
cURL 的基本传输选项:
| 名称 | 描述 |
|---|---|
| CURLOPT_URL | 需要获取的 URL 地址 |
| CURLOPT_HEADER | 启用时会将头文件的信息作为数据流输出 |
| CURLOPT_HTTPHEADER | 设置 HTTP 头字段数组 |
| CURLOPT_SSL_VERIFYPEER | 禁用后 cURL 将终止从服务端进行 SSL 验证 |
| CURLOPT_SSL_VERIFYHOST | 禁用后 cURL 将终止从服务端进行 SSL 验证 |
| CURLOPT_POST | 启用时会发送一个常规的 POST 请求,类似于表单 |
| CURLOPT_POSTFIELDS | 使用 POST 发送的数据数组 |
| CURLOPT_RETURNTRANSFER | 将 cURL 获取的响应结果直接返回,而不是直接输出 |
| CURLOPT_REFERER | 设置 HTTP 请求头 Referer |
cURL 基本使用
使用 cURL 可以模拟浏览器发送请求、自定义请求头、模拟表单提交等。
示例:cURL
入口页面(index.php):
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.duox.dev/");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$respData = curl_exec($ch);
curl_close($ch);
print_r($respData);
示例效果:
