繁体   English   中英

file_get_contents编码出现问题

[英]Issue with file_get_contents encoding

我正在获取file_get_contents(uri)并找回无法编码的Json。

我尝试了几种编码和str_replace但是我不太明白问题是什么。

这是我使用file_get_contents json的开头:

string(67702) " {"localidades"

我知道它正在寻找未知字符,那是什么? 是用于,但我不知道如何解决。

我已经尝试过了,但无济于事

    if(substr($s, 0, 2) == chr(0xFF).chr(0xFE)){
      return substr($s,3);
    }
    else{
      return $s;
    }
   }

这是xxd | 从终端头

00000000: fffe 7b00 2200 6c00 6f00 6300 6100 6c00  ..{.".l.o.c.a.l.
00000010: 6900 6400 6100 6400 6500 7300 2200 3a00  i.d.a.d.e.s.".:.
00000020: 2000 5b00 7b00 2200 6900 6400 4c00 6f00   .[.{.".i.d.L.o.
00000030: 6300 6100 6c00 6900 6400 6100 6400 2200  c.a.l.i.d.a.d.".
00000040: 3a00 2000 3300 2c00 2200 6c00 6f00 6300  :. .3.,.".l.o.c.
00000050: 6100 6c00 6900 6400 6100 6400 2200 3a00  a.l.i.d.a.d.".:.
00000060: 2000 2200 4200 7500 6500 6e00 6f00 7300   .".B.u.e.n.o.s.
00000070: 2000 4100 6900 7200 6500 7300 2200 2c00   .A.i.r.e.s.".,.
00000080: 2200 6900 6400 5000 7200 6f00 7600 6900  ".i.d.P.r.o.v.i.
00000090: 6e00 6300 6900 6100 2200 3a00 2000 2200  n.c.i.a.".:. .".

您拥有的是UTF-16LE,其中每个代码点至少被编码为两个字节,甚至是“基本ASCII”。 文档的前两个字节是字节顺序标记[BOM],它声明这些代码点以什么字节顺序[endian]编码。

$input = "\xff\xfe{\x00}\x00"; // UTF-16-LE with BOM

function convert_utf16($input, $charset=NULL) {
    // if your data has no BOM you must explicitly define the charset.
    if( is_null($charset) ) {
        $bom = substr($input, 0, 2);
        switch($bom) {
            case "\xff\xfe":
                $charset = "UTF-16LE";
                break;
            case "\xfe\xff":
                $charset = "UTF-16BE";
                break;
            default:
                throw new \Exception("No encoding specified, and no BOM detected");
                break;
        }
        $input = substr($input, 2);
    }
    return mb_convert_encoding($input, "UTF-8", $charset);
}

$output = convert_utf16($input);

var_dump(
    $output,
    bin2hex($output),
    json_decode($output, true)
);

输出:

string(2) "{}"
string(4) "7b7d"
array(0) {
}

还需要注意的是,使用UTF-8以外的任何其他格式对JSON进行编码都会使其变为无效JSON,并且您应该告诉提供此数据的人以修复其应用。

您得到的是UTF-16 LE fffe之初被称为BOM 您可以使用iconv

$data = iconv( 'UTF-16', 'UTF-8', $data);

现在您有了带有BOMUTF-8 我认为可以与json_decode一起json_decode ,因为PHP似乎可以处理它。 不过,如果您要删除BOM (应删除该BOM )(请参阅@Sammitch注释),则也可以使用此BOM

$data = preg_replace("/^pack('H*','EFBBBF')/", '', $data);

我重新创建了文件的一部分,我得到了:

$data = file_get_contents('/var/www/html/utf16le.json');
$data = preg_replace("/^pack('H*','EFBBBF')/", '', iconv( 'UTF-16', 'UTF-8', $data));
print_r(json_decode($data));

输出:

stdClass Object
(
    [localidades] => Array
        (
            [0] => stdClass Object
                (
                    [idLocalidad] => 3
                    [localidad] => Buenos Aires
                )

        )

)

xxd

在此处输入图片说明

您尝试处理的文件使用UTF-16编码,PHP本身不支持。 因此,为了对其进行处理,您必须先删除BOM表头(前两个字节),然后使用iconv或mbstring将编码转换为UTF-8。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM