一句话记住核心区别 :
cURL是"你主动发请求给别人",header()是"你告诉浏览器怎么处理你的返回"。
一、先搞清方向:HTTP 通信的两个角色
在 Web 开发中,PHP 脚本可以扮演两种角色:
| 角色 | 行为 | 使用工具 |
|---|---|---|
| 客户端(Client) | 主动调用其他服务器(如微信 API、支付接口) | cURL |
| 服务器(Server) | 响应浏览器或前端 AJAX 请求 | header() |
✅ 所以:
- 当你用 PHP 调别人接口 → 用
cURL - 当你用 PHP 给前端返回数据 → 用
header()
二、cURL:PHP 作为"客户端"发请求
✅ 典型场景
- 调用微信支付
- 获取天气 API 数据
- 向第三方推送消息
🔧 最简 POST JSON 示例
ruby
$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 接口)
css
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => 'success']);
2. 重定向(跳转)
perl
header('Location: /dashboard.php');
exit; // ⚠️ 必须加 exit!
3. 强制下载文件
less
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="report.pdf"');
readfile('report.pdf');
4. 禁止缓存
less
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"