使用PHP Curl调用Google FCM HTTP v1接口时遭遇411错误求助
解决FCM API推送HTTP 411 Length Required错误的方案
我来帮你排查这个头疼的411问题!你已经尝试了不少方法,但大概率是踩了PHP cURL的几个细节坑,咱们一步步捋清楚:
核心问题分析
你提到Postman能正常请求,但PHP代码不行,而且明明加了Content-Length头还是报错,主要问题出在这几个地方:
trim($payload)完全无效:trim()是处理字符串的函数,你把它用在数组$payload上不会有任何作用,反而可能干扰json_encode的正常编码。- 手动设置
Content-Length的两个错误:- 头格式错误:
'Content-length:'.strlen($json)里冒号后面没有空格,HTTP头的标准格式是键: 值,缺少空格会导致服务器无法识别这个头。 - 手动计算容易出错:cURL其实会自动根据POST内容计算并添加正确的
Content-Length,手动设置反而可能和实际发送的字节数不匹配,触发411错误。
- 头格式错误:
Authorization头的潜在格式问题:你的代码里Bearer后面没有空格,虽然这不是当前411的直接原因,但会导致后续授权失败,必须修正。
修正后的完整代码
$topic = 'topic'; $projectId = 'projectid'; $title = 'hahaha'; $content = 'lol'; $payload = array( 'message' => array( 'topic' => $topic, 'notification' => array( 'title' => $title, 'body' => $content, ) ) ); // 直接编码数组,trim对数组无效,完全不需要 $json = json_encode($payload); $headers = array( // 重点:Bearer后面必须加空格 'Authorization: Bearer ' . $this->getFcmApiAccessToken(), // 标准的Content-Type写法,明确编码格式 'Content-Type: application/json; charset=UTF-8' // 移除手动设置的Content-Length,让cURL自动处理 ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send"); curl_setopt($ch, CURLOPT_POST, true); // 如果不需要查看响应头,设为0更方便查看返回的JSON结果 curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 生产环境强烈建议开启SSL验证,避免安全风险 // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); // 新增cURL错误排查,方便定位问题 $result = curl_exec($ch); if(curl_errno($ch)){ echo 'Curl请求错误: ' . curl_error($ch); } // 可选:查看实际发送的请求头,确认参数是否正确 // $requestHeader = curl_getinfo($ch, CURLINFO_REQUEST_HEADER); // var_dump($requestHeader); curl_close($ch); var_dump($result); exit;
额外排查建议
如果修改后还是有问题,可以通过curl_getinfo($ch, CURLINFO_REQUEST_HEADER)查看实际发送的请求头,确认Content-Length是否被cURL正确添加,以及其他头的格式是否合规。
内容的提问来源于stack exchange,提问作者dabeige
相关产品推荐
相关产品推荐

