PHP调用FCM推送阿拉伯语内容报JSON解析错误求助
解决PHP FCM推送阿拉伯语时的JSON解析错误
这个问题我之前也碰到过,根源确实是编码处理不当导致json_encode失败,最终发送给FCM的内容是空的或者无效JSON,才会触发JSON_PARSING_ERROR: Unexpected token END OF FILE at position 0。下面是具体的解决方案:
1. 确保所有字符串是UTF-8编码
FCM要求请求的JSON必须是UTF-8编码,而阿拉伯语如果来自数据库、文件或者用户输入,可能是其他编码(比如Windows-1256)。你需要先将内容转换为UTF-8:
// 检测并转换标题的编码 $title = mb_convert_encoding($title, 'UTF-8', mb_detect_encoding($title)); // 检测并转换内容的编码 $body = mb_convert_encoding($body, 'UTF-8', mb_detect_encoding($body));
如果知道原始编码(比如从MySQL获取的是utf8mb4),可以直接指定,避免检测错误:
$title = mb_convert_encoding($title, 'UTF-8', 'utf8mb4');
2. 正确使用json_encode并检查编码结果
PHP的json_encode在遇到非UTF-8字符时会返回false,如果直接把这个false作为请求体发送,FCM收到的就是空内容,自然会报EOF错误。所以一定要加上JSON_UNESCAPED_UNICODE参数(避免转义Unicode字符,让JSON更简洁),并且检查编码是否成功:
// 构建FCM推送负载 $payload = [ 'notification' => [ 'title' => $title, 'body' => $body ], 'to' => '你的设备Token' ]; // 编码JSON,同时启用Unicode不转义 $jsonPayload = json_encode($payload, JSON_UNESCAPED_UNICODE); // 检查编码是否失败 if ($jsonPayload === false) { die('JSON编码失败: ' . json_last_error_msg()); }
3. 额外注意事项
- PHP文件编码:确保你的PHP源码文件本身是UTF-8无BOM格式,不然字符串常量中的阿拉伯语可能一开始就编码错误。
- 数据库连接编码:如果从MySQL获取阿拉伯语内容,要设置连接编码为
utf8mb4(支持更多特殊字符),比如执行SET NAMES utf8mb4;。 - 请求头设置:发送请求时必须指定
Content-Type: application/json,告诉FCM你发送的是JSON格式数据。
最后附上完整的发送示例:
// 处理编码 $title = mb_convert_encoding("أهلاً بالعالم", 'UTF-8', mb_detect_encoding("أهلاً بالعالم")); $body = mb_convert_encoding("هذا هو رسالة إعلامية من FCM", 'UTF-8', mb_detect_encoding("هذا هو رسالة إعلامية من FCM")); // 构建负载 $payload = [ 'notification' => [ 'title' => $title, 'body' => $body, 'sound' => 'default' ], 'to' => 'DEVICE_TOKEN_HERE' ]; // 编码JSON $jsonPayload = json_encode($payload, JSON_UNESCAPED_UNICODE); if ($jsonPayload === false) { die('JSON编码错误: ' . json_last_error_msg()); } // 发送请求到FCM $ch = curl_init('https://fcm.googleapis.com/fcm/send'); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: key=YOUR_FCM_SERVER_KEY' ]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (curl_errno($ch)) { die('CURL错误: ' . curl_error($ch)); } curl_close($ch); // 输出FCM响应 echo $response;
内容的提问来源于stack exchange,提问作者Younis
相关产品推荐
相关产品推荐

