卷曲得到响应使用UTF-8 BOM(cURL gets response with utf-8 BO

2019-09-22 15:58发布

在我的剧本我用卷曲发送数据,并启用CURLOPT_RETURNTRANSFER。 响应是JSON编码数据。 当我试图json_decode,则返回null。 后来我发现,响应包含UTF-8 BOM符号的字符串的开始(我»¿)。

有一些实验:


$data = $data = curl_exec($ch);
echo $data;

结果为{ “field_1”: “文本1”, “field_2”: “文本_2”, “field_3”: “text_3”}

$data = $data = curl_exec($ch);
echo mb_detect_encoding($data);

结果 - UTF-8

$data = $data = curl_exec($ch);
echo mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data));
// identical to echo mb_convert_encoding($data, 'UTF-8', 'UTF-8');

结果 - { “field_1”: “文本1”, “field_2”: “_2”, “field_3”: “text_3”}


有一两件事可以帮助是消除前3个符号:

if (substr($data, 0, 3) == pack('CCC', 239, 187, 191)) {
    $data = substr($data, 3);
}

但是,如果还会有什么其他BOM? 所以,问题是:如何检测卷曲响应的正确的编码? 或如何来检测一下BOM已经arrrived? 或者,也许如何与BOM响应转换?

Answer 1:

恐怕你已经找到了答案自己 - 这是坏消息,有没有更好的答案,我知道的。

该BOM不应该在那里,它是发送者的责任,不把它一起。

但我可以向你保证,在BOM或者是有还是没有,如果是,这是你所知道的3个字节。

你可以有一个稍快,处理另外N物料清单的小改动:

$__BOM = pack('CCC', 239, 187, 191);
// Careful about the three ='s -- they're all needed.
while(0 === strpos($data, $__BOM))
    $data = substr($data, 3);

第三方BOM探测器不会做任何不同。 你在稍后的时间卷曲包括在内,即使这样,开始剥离不需要的物料清单。

可能的原因

一些JSON优化器和过滤器可以决定输出需要一个BOM。 此外,也许更简单地说,谁写的脚本生成的JSON开幕PHP标签之前无意中包含一个BOM。 Apache的,不关心的BOM是什么,看到有开始标记之前的数据,所以一起发送,并从PHP流本身隐藏它。 这可以偶尔也导致“无法添加标题:输出已经开始”的错误。

内容检测

您可以验证JSON是有效的UTF-8,BOM或不BOM,但需要mb_string支持您必须使用严格模式得到一些边缘情况:

if (false === mb_detect_encoding($data, 'UTF-8', true)) {
    // JSON contains invalid sequences (erroneously NOT JSON encoded)
}

我建议不要试图纠正可能的编码错误; 你可能会打破自己的代码,并且还具有维护别人的工作。



Answer 2:

此页面详细介绍了类似的问题: BOM中由WordPress生成的PHP页面自动

基本上,它可以发生在JSON生成使用PHP编写和编辑已在开幕前的BOM不知何故悄悄<?php标签。 由于您的客户端语言是PHP我假设这是相关的。

你可以剥离出来使用substr比较-一个BOM永远只发生在一个文档的开始。 但如果你有控制权的JSON源,你应该从源文件,而不是删除BOM。



Answer 3:

绝不会有的“{”之前超过3个字符。 这些3个字符是UTF-8的一个字符。 所以,如果你只是做$数据= SUBSTR($的数据,3); 你会好起来的。

看看这里了解更多信息: json_decode Web服务调用后返回NULL



文章来源: cURL gets response with utf-8 BOM