下面这一份是 “PHP cURL 新手 → 高手”完整实战教程”,包含:
✔ 全覆盖 cURL 的最常用功能
✔ 单请求、POST、文件上传、Header、自定义方法
✔ HTTPS、Cookie、代理、重定向、错误处理
✔ 并发多线程 curl_multi
✔ API 调用模板(可复制)
✔ 安全注意事项(避免 SSRF、超时死锁)
✔ 生产级封装示例
你只要跟着每一节照做,就能直接从入门冲到熟练开发者级别。
🧩 一、什么是 cURL?为什么必须会?
cURL 是 PHP 中最强大的 HTTP 客户端:
- 访问 API(微信、Stripe、支付、登录等)
- 上传文件
- 模拟浏览器(带 Cookie / Header)
- 抓取网页(爬虫)
- 使用代理
- 并发请求(curl_multi)
- 超时控制、错误处理更稳
file_get_contents 在生产环境远不如 cURL。
🧱 二、最基本用法(GET 请求)
$url = "https://httpbin.org/get";
$ch = curl_init();
// 设置 URL
curl_setopt($ch, CURLOPT_URL, $url);
// 返回内容,而不是直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
📌 重点参数解释
| 参数 | 作用 |
|---|---|
CURLOPT_RETURNTRANSFER=true | 返回字符串而不是 echo |
CURLOPT_URL | 目标 URL |
你已经会最基本的 GET。
📮 三、POST 请求(表单)
$url = "https://httpbin.org/post";
$data = [
"username" => "Jack",
"password" => "123456"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
自动发送Content-Type: application/x-www-form-urlencoded
📦 四、发送 JSON(现代 API 99% 用这个)
$url = "https://httpbin.org/post";
$data = [
"name" => "Ajay",
"age" => 18
];
$payload = json_encode($data);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Content-Length: " . strlen($payload)
]
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
🧻 五、带 Header 的请求
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Accept: application/json",
"User-Agent: MyApp/1.0",
"Authorization: Bearer YOUR_TOKEN"
]);
📤 六、上传文件(multipart/form-data)
PHP ≥ 5.5 使用 CURLFile:
$url = "https://example.com/upload";
$data = [
"file" => new CURLFile("/path/to/a.jpg", "image/jpeg", "a.jpg")
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
curl_close($ch);
echo $res;
🔁 七、自动跟随重定向
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
浏览器式体验。
🧈 八、处理 HTTPS(关闭/强制验证)
✔ 慎用——新增 SSRF 过滤时常用
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 不验证证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 不验证域名
生产环境要 开启验证!
🍪 九、Cookie(模拟登录)
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
🕳 十、代理(常用爬虫)
curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:7890");
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
// SOCKS5
// curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
🧨 十一、错误处理(重要)
$res = curl_exec($ch);
if ($res === false) {
echo "Error: " . curl_error($ch);
} else {
echo $res;
}
curl_close($ch);
🚀 十二、并发多线程(curl_multi)高手必会
让十个接口一起访问,比循环快几十倍。
$urls = [
"https://httpbin.org/get?a=1",
"https://httpbin.org/get?a=2",
"https://httpbin.org/get?a=3",
];
$multi = curl_multi_init();
$chs = [];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multi, $ch);
$chs[$i] = $ch;
}
$running = null;
do {
curl_multi_exec($multi, $running);
} while ($running);
foreach ($chs as $ch) {
echo curl_multi_getcontent($ch), "\n\n";
curl_multi_remove_handle($multi, $ch);
}
curl_multi_close($multi);
你已经具备“高并发 API 调用能力”。
🧩 十三、生产级封装(直接复制即可)
function http_request($url, $method = "GET", $body = null, $headers = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
switch (strtoupper($method)) {
case "POST":
curl_setopt($ch, CURLOPT_POST, true);
break;
case "PUT":
case "DELETE":
case "PATCH":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
break;
}
if ($body) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
if ($headers) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$res = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
return $err ? ["error" => $err] : $res;
}
使用示例:
echo http_request("https://httpbin.org/get");
echo http_request(
"https://httpbin.org/post",
"POST",
json_encode(["a" => 1]),
["Content-Type: application/json"]
);
🛡 十四、必须掌握的安全要点(防 SSRF)
真实项目中,URL 来自用户输入是非常危险的:
1) 设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
2) 禁止内部地址访问
(防止访问 127.0.0.1、169.254.169.254 元数据)
3) 禁止 file:// gopher:// 等危险协议
$scheme = parse_url($url, PHP_URL_SCHEME);
if (!in_array($scheme, ["http", "https"])) exit("blocked");
🎯 十五、常见问题速查
Q1:POST JSON 怎么总是被当表单?
→ 必须手动加 Content-Type: application/json
Q2:返回中文乱码?
→ 加:
curl_setopt($ch, CURLOPT_ENCODING, "");
Q3:代理不生效?
→ 确认代理类型是 HTTP / SOCKS5