推荐使用 laravel http 客户端的 asform() 方法发送 application/x-www-form-urlencoded 请求;若必须用原生 curl,需用 http_build_query 编码参数、设置 curlopt_postfields 和 content-type 头,并启用 returntransfer。

在 Laravel 7 中,不推荐直接使用原生 cURL 发送 application/x-www-form-urlencoded 请求,因为框架已内置更安全、简洁、可测试的 HTTP 客户端(基于 Guzzle),且能自动处理编码、重试、错误抛出等细节。但若因特殊场景必须用原生 cURL(如绕过 Laravel 的中间件、调试底层行为或集成遗留代码),以下是清晰、可靠的做法。
用原生 cURL 发送 FormUrlEncoded 请求
关键在于:正确设置请求方法、数据编码方式、Content-Type 头,并确保参数是普通键值对(非 JSON 字符串)。
- 调用
curl_init()初始化句柄,传入目标 URL - 使用
http_build_query($params)将关联数组转为key=value&key2=value2格式 - 设置
CURLOPT_POST => 1和CURLOPT_POSTFIELDS为上述查询字符串 - 显式声明请求头:
Content-Type: application/x-www-form-urlencoded - 启用
CURLOPT_RETURNTRANSFER => true获取响应体而非直接输出 - 记得调用
curl_close()释放资源
用 Laravel HTTP 客户端替代(推荐)
Laravel 7+ 的 Http 门面默认以 JSON 方式发送 POST 数据。要发 application/x-www-form-urlencoded,需显式调用 asForm():
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
-
Http::asForm()->post($url, $params)—— 自动设置 header 并编码参数 - 支持链式配置:超时、token、重试等,例如
Http::timeout(10)->asForm()->post(...) - 响应对象提供
body()、json()、successful()等便捷方法 - 无需手动安装 Guzzle(只要已执行
composer require guzzlehttp/guzzle)
常见错误与规避
容易出错的地方集中在编码和头设置上:
- 误用
json_encode($params)传给CURLOPT_POSTFIELDS→ 导致服务端收到的是 JSON 字符串,不是表单字段 - 漏设
Content-Type或设成application/json→ 接口可能拒绝解析或返回 415 错误 - 参数含中文或特殊字符但未用
http_build_query→ 编码乱、服务端接收为空或截断 - 在 Laravel 测试中用原生 cURL → 难以 mock、无法利用
withoutMiddleware()等特性,建议统一用Http::fake()
验证是否成功发送
最直接的方式是在接收方接口中打印原始输入:
- PHP 端检查
$_POST是否有预期键值(非file_get_contents('php://input'),后者对 form-data 无效) - 用
dd(request()->all())查看 Laravel 控制器中解析后的全部请求数据 - 开启 cURL 的
CURLOPT_HEADER => true查看完整请求头,确认 Content-Type 和 Content-Length 正确










