第十四章-PHP与HTTP协议

第十四章-PHP与HTTP协议

一,HTTP 协议详解

HTTP(H yperT ext T ransfer Protocol,超文本传输协议)是互联网上应用最广泛的协议之一,用于客户端(如浏览器)与服务器之间的通信。它是 Web 技术的基石,理解 HTTP 协议是开发 Web 应用的核心基础。以下是 HTTP 协议的全面解析:


一、HTTP 协议基础

1. 协议特性
  • 无状态 (Stateless)
    每个 HTTP 请求相互独立,服务器默认不保存客户端状态(如用户登录信息)。状态管理需通过 Cookie、Session 或 Token 实现。
  • 基于请求-响应模型
    • 客户端 发送请求(Request) → 服务器返回响应(Response)。
    • 支持多种数据格式:HTML、JSON、XML、图片、视频等。
  • 灵活可扩展
    • 通过 HTTP 头部(Headers) 扩展功能(如缓存控制、内容协商)。
    • 支持 HTTPS(HTTP + SSL/TLS)加密传输。
2. 协议版本
版本 年份 核心改进
HTTP/0.9 1991 仅支持 GET 方法,返回纯文本
HTTP/1.0 1996 支持 MIME 类型、状态码、Header
HTTP/1.1 1999 持久连接、管道化、Host 头
HTTP/2 2015 二进制协议、多路复用、头部压缩
HTTP/3 2022 基于 QUIC 协议(UDP)、减少延迟

二、HTTP 消息结构

1. 请求(Request)
http 复制代码
GET /index.html HTTP/1.1             # 请求行:方法 + 路径 + 协议版本
Host: www.example.com                # 头部字段(Headers)
User-Agent: Mozilla/5.0
Accept: text/html
                                      # 空行(分隔头部和消息体)
                                      # 消息体(Body,GET 请求通常为空)
  • 请求方法 (Methods)

    方法 用途 幂等性
    GET 获取资源(参数在 URL)
    POST 提交数据(参数在 Body)
    PUT 更新完整资源
    DELETE 删除资源
    PATCH 更新部分资源
    HEAD 获取响应头(无 Body)
    OPTIONS 查询服务器支持的通信选项
2. 响应(Response)
http 复制代码
HTTP/1.1 200 OK                       # 状态行:协议版本 + 状态码 + 状态描述
Content-Type: text/html               # 头部字段(Headers)
Content-Length: 1234
Date: Mon, 01 Jan 2024 12:00:00 GMT
                                      # 空行
<!DOCTYPE html>                       # 消息体(Body)
<html>...</html>
  • 状态码 (Status Codes)

    状态码 类别 常见示例
    1xx 信息响应 100(继续)
    2xx 成功 200(OK)、201(Created)
    3xx 重定向 301(永久重定向)、304(未修改)
    4xx 客户端错误 400(错误请求)、403(禁止访问)
    5xx 服务端错误 500(内部错误)、503(服务不可用)

三、核心机制详解

1. 连接管理
  • 短连接 (HTTP/1.0)
    每次请求后关闭 TCP 连接,效率低。
  • 持久连接 (HTTP/1.1)
    • 默认保持 TCP 连接复用(Connection: keep-alive)。
    • 通过 Content-LengthTransfer-Encoding: chunked 处理动态内容。
  • 多路复用 (HTTP/2)
    单个 TCP 连接上并行传输多个请求/响应,解决队头阻塞问题。
2. 缓存机制
  • 强缓存
    • Cache-Control: max-age=3600:资源有效期 1 小时。
    • Expires: Mon, 01 Jan 2024 12:00:00 GMT(HTTP/1.0,已被取代)。
  • 协商缓存
    • Last-Modified + If-Modified-Since:基于时间戳。
    • ETag + If-None-Match:基于内容哈希值。
3. 内容协商

客户端通过 Header 声明偏好,服务器返回最合适的内容:

  • Accept: text/html, application/json(内容类型)
  • Accept-Language: en-US, zh-CN(语言)
  • Accept-Encoding: gzip, deflate(压缩方式)
4. 安全机制
  • HTTPS

    • HTTP over SSL/TLS,加密传输数据。
    • 通过数字证书验证服务器身份。
  • CORS (跨域资源共享)

    http 复制代码
    Access-Control-Allow-Origin: https://trusted-site.com
    Access-Control-Allow-Methods: GET, POST

四、HTTP 头部关键字段

常用请求头
字段 用途
Host 目标域名(HTTP/1.1 必需)
User-Agent 客户端标识(浏览器、操作系统)
Cookie 发送服务器设置的 Cookie
Authorization 认证凭证(如 Bearer <token>
Content-Type 请求体的 MIME 类型(如 application/json
常用响应头
字段 用途
Set-Cookie 设置客户端的 Cookie
Location 重定向目标 URL(配合 3xx 状态码)
Content-Encoding 内容压缩方式(如 gzip
Cache-Control 缓存策略(如 no-cache
Content-Security-Policy 防止 XSS 攻击

二,常见的HTTP 响应设置

一、基础响应设置

1. 设置 HTTP 状态码
php 复制代码
// 直接设置状态码 (PHP >= 5.4)
http_response_code(404); // 返回 404 Not Found

// 传统方式(兼容旧版本)
header("HTTP/1.1 403 Forbidden");
2. 设置响应内容类型
php 复制代码
// 返回 HTML
header('Content-Type: text/html; charset=utf-8');

// 返回 JSON(API 开发必备)
header('Content-Type: application/json; charset=utf-8');

// 返回纯文本
header('Content-Type: text/plain');

// 返回 XML
header('Content-Type: application/xml');

二、重定向与页面跳转

1. 基础重定向
php 复制代码
// 302 临时重定向(默认)
header('Location: /new-page.php');
exit; // 必须立即终止脚本执行

// 301 永久重定向
header('Location: /permanent-page.php', true, 301);
exit;
2. 延迟重定向
php 复制代码
// 3 秒后跳转
header('Refresh: 3; url=/target-page.php');
echo '即将跳转,请稍候...';

三、缓存控制

1. 禁止浏览器缓存
php 复制代码
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP/1.1
header('Pragma: no-cache'); // HTTP/1.0
header('Expires: 0'); // 代理服务器缓存
2. 设置资源缓存时间
php 复制代码
// 缓存 1 小时(适用于静态资源)
header('Cache-Control: public, max-age=3600');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');

四、文件操作相关

1. 文件下载
php 复制代码
$filePath = '/path/to/file.zip';

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));

readfile($filePath);
exit;
2. 断点续传支持
php 复制代码
header('Accept-Ranges: bytes');
header('Content-Length: ' . filesize($filePath));

五、安全相关头部

1. 防止点击劫持
php 复制代码
header('X-Frame-Options: DENY'); // 或 SAMEORIGIN
2. 内容安全策略(CSP)
php 复制代码
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com");
3. 禁用 MIME 类型嗅探
php 复制代码
header('X-Content-Type-Options: nosniff');

六、跨域资源共享(CORS)

1. 简单跨域请求
php 复制代码
header('Access-Control-Allow-Origin: *'); // 允许所有域名(慎用)
header('Access-Control-Allow-Origin: https://trusted-site.com'); // 指定域名
2. 预检请求处理
php 复制代码
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Max-Age: 86400'); // 缓存预检结果 24 小时
    exit;
}

七、Cookie 操作

php 复制代码
setcookie(
    'user_token',          // Cookie 名称
    'abc123xyz',           // 值
    time() + 3600,         // 过期时间(1 小时)
    '/',                   // 有效路径
    '.example.com',        // 域名(支持子域名)
    true,                  // 仅 HTTPS 传输
    true                   // 禁止 JavaScript 访问(HttpOnly)
);
php 复制代码
setcookie('user_token', '', time() - 3600, '/', '.example.com', true, true);

八、高级场景示例

1. 构建 JSON API
php 复制代码
try {
    $data = ['status' => 'success', 'data' => fetchData()];
    http_response_code(200);
} catch (Exception $e) {
    $data = ['status' => 'error', 'message' => $e->getMessage()];
    http_response_code(500);
}

header('Content-Type: application/json');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
2. 强制下载大文件(内存优化)
php 复制代码
$file = fopen('large-file.iso', 'rb');

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="large-file.iso"');

while (!feof($file)) {
    echo fread($file, 8192); // 分块输出
    ob_flush();
    flush();
}

fclose($file);
exit;

关键注意事项

  1. 输出顺序问题

    • 所有 header() 调用必须在任何实际输出(包括空格和空行)之前
    • 使用 ob_start() 开启输出缓冲可避免报错
  2. 编码一致性

    php 复制代码
    header('Content-Type: text/html; charset=utf-8');
    // 同时设置 PHP 内部编码
    mb_internal_encoding('UTF-8');
  3. 性能优化

    • 避免频繁设置重复头部
    • 使用 header_remove() 清除不需要的默认头部
  4. 安全防护

    • 敏感操作后立即调用 session_regenerate_id()
    • 使用 header('X-XSS-Protection: 1; mode=block') 启用浏览器 XSS 过滤

三, PHP模拟 HTTP 请求

一、使用 file_get_contents() 发送请求

适用于简单 GET/POST 请求,需开启 allow_url_fopen 配置。

1. 发送 GET 请求
php 复制代码
$url = 'https://api.example.com/data?param1=value1&param2=value2';
$response = file_get_contents($url);
echo $response;
2. 发送 POST 请求(表单数据)
php 复制代码
$url = 'https://api.example.com/submit';
$data = ['key1' => 'value1', 'key2' => 'value2'];

$options = [
    'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/x-www-form-urlencoded',
        'content' => http_build_query($data)
    ]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
echo $response;
3. 发送 POST 请求(JSON 数据)
php 复制代码
$url = 'https://api.example.com/submit';
$data = json_encode(['name' => 'Alice', 'age' => 30]);

$options = [
    'http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/json\r\n",
        'content' => $data
    ]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
echo $response;

二、使用 cURL 扩展

功能更强大,支持 HTTPS、头部设置、文件上传等。

1. 基础 GET 请求
php 复制代码
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应内容
$response = curl_exec($ch);
curl_close($ch);
echo $response;
2. 发送 POST 请求(表单数据)
php 复制代码
$url = 'https://api.example.com/submit';
$data = ['username' => 'test', 'password' => '123456'];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($data),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded'
    ]
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
3. 发送 POST 请求(JSON 数据)
php 复制代码
$url = 'https://api.example.com/submit';
$data = json_encode(['title' => 'Test', 'content' => 'Hello World']);

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $data,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer abc123xyz'
    ]
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

三、处理 HTTPS 与 SSL 验证

1. 忽略 SSL 证书验证(仅限测试环境)
php 复制代码
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
2. 指定 CA 证书
php 复制代码
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');

四、文件上传

php 复制代码
$filePath = '/path/to/file.jpg';
$data = [
    'file' => new CURLFile($filePath, 'image/jpeg', 'photo.jpg'),
    'description' => 'My photo'
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://api.example.com/upload',
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $data,
    CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

五、处理 Cookies

1. 发送时携带 Cookies
php 复制代码
curl_setopt($ch, CURLOPT_COOKIE, 'session_id=abc123; user_token=xyz789');
2. 保存响应 Cookies
php 复制代码
curl_setopt($ch, CURLOPT_COOKIEJAR, '/path/to/cookies.txt'); // 保存到文件
curl_setopt($ch, CURLOPT_COOKIEFILE, '/path/to/cookies.txt'); // 读取 Cookies

六、高级配置

1. 设置超时时间
php 复制代码
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30 秒超时
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时 10 秒
2. 处理重定向
php 复制代码
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动跟随重定向
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 最大重定向次数
3. 获取响应头信息
php 复制代码
curl_setopt($ch, CURLOPT_HEADER, true); // 包含头信息在输出中

$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);

echo "Headers:\n$headers\nBody:\n$body";

七、错误处理

php 复制代码
$ch = curl_init();
// ... 设置选项 ...

$response = curl_exec($ch);
if ($response === false) {
    $error = curl_error($ch);
    $errno = curl_errno($ch);
    echo "cURL 错误 ($errno): $error";
} else {
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "HTTP 状态码: $httpCode\n响应内容:\n$response";
}
curl_close($ch);

八、完整示例:调用 REST API

php 复制代码
function callApi($url, $method = 'GET', $data = null, $headers = []) {
    $ch = curl_init();
    $options = [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => strtoupper($method),
        CURLOPT_HTTPHEADER => $headers
    ];

    if ($method !== 'GET' && $data !== null) {
        $options[CURLOPT_POSTFIELDS] = is_array($data) ? json_encode($data) : $data;
    }

    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return [
        'code' => $httpCode,
        'data' => json_decode($response, true),
        'error' => $error
    ];
}

// 调用示例
$result = callApi(
    'https://api.example.com/users',
    'POST',
    ['name' => 'Alice', 'email' => 'alice@example.com'],
    ['Content-Type: application/json', 'Authorization: Bearer token123']
);

print_r($result);

注意事项

  1. 安全建议
    • 生产环境务必启用 SSL 证书验证
    • 敏感数据(如 API 密钥)不要硬编码在代码中
    • 对用户输入做严格过滤
  2. 性能优化
    • 复用 cURL 句柄(使用 curl_init() 一次,多次请求)
    • 设置合理的超时时间
  3. 第三方库推荐
    如需更复杂功能,可使用:
    • Guzzle HTTPcomposer require guzzlehttp/guzzle
    • Symfony HTTP Clientcomposer require symfony/http-client

相关推荐
不可能的是1 天前
前端 SSE 流式请求三种实现方案全解析
前端·http
BingoGo1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1235 天前
matlab画图工具
开发语言·matlab