curl_init()后必须调用curl_exec()才能真正发送请求,否则仅配置参数而无网络调用;需设CURLOPT_RETURNTRANSFER=>true捕获响应,避免直接输出;GET用URL传参,POST用CURLOPT_POSTFIELDS传数据;布尔选项务必用true/false而非1/0。

curl_init() 之后必须调用 curl_exec() 才会真正发请求
很多人写完 curl_init() 和一堆 curl_setopt() 就以为请求已经发出去了,结果变量里啥也没有——因为漏掉了最关键的一步:curl_exec()。它才是真正触发网络调用的函数,不调用它,curl 只是配好了参数,没干活。
常见错误现象:$response 是 null 或空字符串,curl_error($ch) 却返回空,说明根本没执行;或者程序卡住几秒后超时,其实是 curl_exec() 被跳过了,但后续逻辑误以为在等响应。
- 每次调用
curl_init()后,必须跟一个curl_exec() - 如果需要获取响应体,要提前设置
CURLOPT_RETURNTRANSFER => true,否则curl_exec()默认直接输出到 stdout(页面上刷出一串 JSON 就是这个原因) - 别在
curl_exec()前加return或提前exit,否则请求永远不会发出
GET 请求只需拼 URL,POST 请求必须设 CURLOPT_POSTFIELDS
GET 和 POST 的本质区别不在函数名,而在数据怎么传:GET 把参数塞进 URL 查询字符串,POST 把数据放在请求体里。PHP 的 curl 不会自动帮你做这个区分,全靠你手动控制。
使用场景:调第三方 API,比如拉用户列表用 GET,提交表单用 POST;有些接口严格校验 Content-Type 或拒绝 URL 里带敏感参数,这时候 POST 是唯一选择。
立即学习“PHP免费学习笔记(深入)”;
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
- GET:把参数用
http_build_query()拼进 URL,例如$url .= '?' . http_build_query($params),然后只设CURLOPT_URL - POST:URL 保持干净,用
CURLOPT_POSTFIELDS传数组(curl 自动设Content-Type: application/x-www-form-urlencoded)或 JSON 字符串(需手动设Content-Type: application/json) - 别用
CURLOPT_POST => true单独开启 POST 模式——它不传任何数据,只会发一个空 body,服务端大概率报错400 Bad Request
curl_setopt() 的布尔值参数容易被 PHP 类型转换坑
curl 很多选项(比如 CURLOPT_SSL_VERIFYPEER、CURLOPT_FOLLOWLOCATION)只接受明确的 true 或 false,传 1、0、"1" 甚至空数组都可能触发非预期行为——尤其是 PHP 8+ 对类型更敏感后。
性能 / 兼容性影响:设错 CURLOPT_SSL_VERIFYPEER => 0 在旧版 PHP 可能只是警告,新版直接报 curl_setopt(): Invalid value for option CURLOPT_SSL_VERIFYPEER;而 CURLOPT_FOLLOWLOCATION => false 写成 0 会导致重定向失效,但无报错,排查起来特别隐蔽。
- 一律用
true/false,别用数字或字符串代替布尔值 -
CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT是整数秒,可以传30,但和布尔值选项别混用同一套习惯 - 不确定某个选项要什么类型?查 PHP 官方文档对应常量的「Type」栏,不是看示例代码里写了啥
没关 curl_close() 不一定内存泄漏,但不设 CURLOPT_RETURNTRANSFER 会破坏页面输出
很多人听说“要用 curl_close()”,就机械地在最后加一行,其实 PHP 在脚本结束时会自动释放 curl handler;真正要命的是忘了设 CURLOPT_RETURNTRANSFER => true,导致响应内容直接 echo 出来,打乱你原本的 JSON 输出或 HTML 结构。
容易踩的坑:API 返回 JSON,你期望用 json_decode($response) 解析,结果 $response 是 null,而浏览器源码里却看到一串原始 JSON——说明响应被直接输出了,$response 根本没捕获到内容。
- 只要需要把响应存进变量,就必须设
CURLOPT_RETURNTRANSFER => true -
curl_close()不是必须的,但显式关闭能让资源释放时机更可控,尤其在长循环里反复请求时 - 别在
curl_exec()前就调curl_close(),那等于拿个废手柄按了发射键
最麻烦的不是语法写错,而是 curl 把响应直接吐到页面上,你还以为自己没拿到数据——盯住输出位置,比盯代码更容易发现问题。


















