一句话记住核心区别:
cURL是“你主动发请求给别人”,header()是“你告诉浏览器怎么处理你的返回”。
一、先搞清方向:HTTP 通信的两个角色
在 Web 开发中,PHP 脚本可以扮演两种角色:
| 角色 | 行为 | 使用工具 |
|---|---|---|
| 客户端(Client) | 主动调用其他服务器(如微信 API、支付接口) | cURL |
| 服务器(Server) | 响应浏览器或前端 AJAX 请求 | header() |
✅ 所以:
- 当你用 PHP调别人接口→ 用
cURL - 当你用 PHP给前端返回数据→ 用
header()
二、cURL:PHP 作为“客户端”发请求
✅ 典型场景
- 调用微信支付
- 获取天气 API 数据
- 向第三方推送消息
🔧 最简 POST JSON 示例
$data = ['user_id' => 123, 'action' => 'login']; $json = json_encode($data); $ch = curl_init(); //初始化 curl_setopt_array($ch, [ CURLOPT_URL => 'https://api.example.com/notify', //设置路径 CURLOPT_POST => true, //是否为post CURLOPT_POSTFIELDS => $json, //post的数据 CURLOPT_RETURNTRANSFER => true, //是否转成字符串 CURLOPT_HTTPHEADER => [ //header请求头 'Content-Type: application/json', // 告诉对方:“我发的是 JSON” 'Authorization: Bearer your_token' ] ]); $response = curl_exec($ch); //执行 curl_close($ch); //关闭
📌 关键点
CURLOPT_HTTPHEADER设置的是请求头(Request Headers)- 必须手动加
'Content-Type: application/json',否则对方可能无法解析 cURL的 Header 是你告诉“目标服务器”的话
三、header():PHP 作为“服务器”响应浏览器
✅ 典型场景
- 返回 JSON 给 AJAX
- 动态生成图片/PDF 并显示
- 登录后跳转页面
- 禁止缓存敏感页面
🔧 常见用法示例
1. 返回 JSON(API 接口)
header('Content-Type: application/json; charset=utf-8'); echo json_encode(['status' => 'success']);
2. 重定向(跳转)
header('Location: /dashboard.php'); exit; // ⚠️ 必须加 exit!
3. 强制下载文件
header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="report.pdf"'); readfile('report.pdf');
4. 禁止缓存
header('Cache-Control: no-cache, no-store, must-revalidate'); header('Pragma: no-cache'); header('Expires: 0');
📌 关键点
header()设置的是响应头(Response Headers)- 必须在任何输出之前调用(不能有 echo、HTML、空格等)
header()的 Header 是你告诉“浏览器/前端”的话
四、对比总结:一张表看懂区别
| 项目 | cURL | header() |
|---|---|---|
| 角色 | 客户端(主动请求别人) | 服务器(被动响应浏览器) |
| 方向 | PHP → 外部服务器 | PHP → 浏览器/前端 |
| Header 类型 | 请求头(Request Header) | 响应头(Response Header) |
| 典型用途 | 调 API、发数据 | 返回 JSON、跳转、下载、设 Cookie |
| 是否需提前输出 | 无限制 | ❌ 必须在任何输出前调用 |
| 常见 Header | Content-Type,Authorization | Content-Type,Location,Cache-Control |
五、高频问题解答(FAQ)
❓ Q1:Content-Type两边都能用?
✅ 是的!但含义不同:
cURL中:“我发的数据是 JSON”header()中:“我返回的数据是 JSON”
❓ Q2:前端发 JSON,我能回 HTML 吗?
✅ 当然可以!只要:
- 后端设
header('Content-Type: text/html') - 前端用
.text()而不是.json()读取
❓ Q3:怎么知道该写什么 MIME 类型?
👉 查 MDN:Common MIME types
或用浏览器 DevTools 看别人网站的响应头。
❓ Q4:header()报错 “Cannot modify header information”?
👉 因为前面已经有输出(空格、echo、BOM 等)。
✅ 解决方案:
- 确保
header()在最顶部 - 或开启输出缓冲:
ob_start();
六、记忆口诀(背这一段就够了)
cURL 是“我说”——我发请求,告诉别人我是谁、发什么格式;
header() 是“我说给你听”——我返回结果,告诉浏览器怎么处理。方向相反,用途不同,千万别混!
七、推荐调试方法
- 看请求头?→ 用 cURL + 日志,或抓包工具(如 Wireshark)
- 看响应头?→ 浏览器按
F12→ Network → 点请求 → 查看Response Headers - 不确定 MIME 类型?→ Google 搜 “mime type pdf”