curl 是 php 发送 http 请求最可靠选择;必须设 curlopt_returntransfer=true 才能获取响应内容,否则 curl_exec() 直接输出;传数组或 json 时需匹配 content-type;get 参数须用 urlencode() 或 http_build_query() 编码;务必检查 curl_getinfo($ch, curlinfo_http_code) 获取真实状态码。

PHP 发送 HTTP 请求,curl 是最可靠、最可控的选择——只要 cURL 扩展已启用(绝大多数生产环境默认开启),就别绕弯用 file_get_contents 去硬凑复杂请求。
curl_init() 后必须设 CURLOPT_RETURNTRANSFER
不设这个选项,curl_exec() 会直接把响应内容输出到页面或 CLI,而不是返回给你处理。一旦你试图 json_decode(curl_exec($ch)) 却没设它,结果就是 null 或解析失败,而错误还不明显。
- 务必在
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)之后再调用curl_exec() - 如果同时用了
curl_setopt($ch, CURLOPT_HEADER, true),响应体里会混入原始响应头,需手动截断或改用CURLINFO_HEADER_SIZE提取 - 设成
false只适合调试时“看一眼”,线上逻辑中基本不用
POST 请求传数组 vs 传 JSON 字符串,Header 必须匹配
CURLOPT_POSTFIELDS 接收数组或字符串,但服务端怎么解析,全看 Content-Type 头是否一致。常见错误是传了 json_encode($data) 却漏设 application/json,导致 API 返回 400 或字段为空。
- 传表单数据:用
http_build_query($data)+Content-Type: application/x-www-form-urlencoded - 传 JSON 数据:用
json_encode($data)+Content-Type: application/json,且建议显式加Content-Length头(curl通常自动补,但某些代理或旧版 Nginx 会校验) - 传文件:必须用
@/path/to/file语法(PHP 5.6+ 推荐用CURLFile类,避免被禁用的@符号)
超时、SSL 和错误检查不能只靠 curl_exec() 返回值
curl_exec() 返回 false 只表示传输层失败(如 DNS 解析失败、连接超时),不代表 HTTP 状态码是错的。200 OK 也可能返回业务错误;500 错误却可能 curl_exec() 成功返回字符串。
- 始终用
curl_getinfo($ch, CURLINFO_HTTP_CODE)拿真实状态码,别信响应体里的 “success”: false - 设
CURLOPT_TIMEOUT(总超时)和CURLOPT_CONNECTTIMEOUT(连接超时),避免卡死进程 - 生产环境慎用
CURLOPT_SSL_VERIFYPEER => false;若证书异常,优先检查系统 CA 证书路径(CURLOPT_CAINFO)而非关验证 - 错误诊断优先看
curl_error($ch),不是error_get_last()
GET 请求参数拼接容易出编码问题
手拼 URL 如 "?name=" . $name . "&id=" . $id 是高危操作:中文、空格、& 符号都会导致请求错乱或被截断。cURL 不会帮你做 URL 编码,得自己来。
- 对每个参数值单独用
urlencode(),不要对整个 query stringurlencode() - 更稳妥的做法:构造关联数组,用
http_build_query($params)生成 query string,再拼到 URL 后 - 如果 URL 已含参数(比如带 hash 或已有 ?),注意用 & 追加,且确保原始部分也经过编码
真正难的不是调通一次请求,而是让每次请求都可预期、可追溯、可降级——比如超时后 fallback 到缓存,或状态码非 2xx 时触发告警。这些逻辑不会写在 curl_setopt 里,但在封装函数里必须留好钩子。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











