Php 无法将JSON响应从windows-1253转换为utf8

Php 无法将JSON响应从windows-1253转换为utf8,php,.net,json,guzzle,Php,.net,Json,Guzzle,我正试图解析来自我无法控制的web服务的JSON响应 这些是标题 这是我在php中看到的隐藏敏感部分的主体 我正在使用guzzle http客户端发送请求并检索响应 如果我尝试直接解码它,我会收到一个空对象,所以我假设需要转换,所以我尝试像这样转换响应内容 json_解码(iconv($charset,$UTF-8',$contents)) 或 mb_convert_编码($contents,'UTF-8',$charset) 两者都会引发异常 注意:iconv():错误的字符集,第205行

我正试图解析来自我无法控制的web服务的JSON响应

这些是标题

这是我在php中看到的隐藏敏感部分的主体

我正在使用guzzle http客户端发送请求并检索响应

如果我尝试直接解码它,我会收到一个空对象,所以我假设需要转换,所以我尝试像这样转换响应内容

json_解码(iconv($charset,$UTF-8',$contents))

mb_convert_编码($contents,'UTF-8',$charset)

两者都会引发异常

注意:iconv():错误的字符集,第205行的Client.php中不允许从“windows-1253”转换为“UTF-8”

警告:mb\u convert\u encoding():Client.php第208行指定的字符编码非法

我以前成功地使用过这段代码,但我不明白为什么它现在失败了

使用POSTMAN发送相同的请求可以正确地检索数据,而不会出现断字符,并且它似乎显示了收到的相同的头和正文

我正在根据评论进行更新

mb\u检测编码($response->getBody())
->UTF-8

mb\u检测编码($response->getBody->getContents())
->ASCII

json\u last\u error\u msg
->格式错误的UTF-8字符,可能编码不正确

此外,作为一次尝试和错误尝试,我尝试了所有iconv编码,以查看是否有任何可以将其转换为utf-8而不会出现错误,以检测使用此编码的编码

        private function detectEncoding($str){
        $iconvEncodings = [...]
        $finalEncoding = "unknown";
        foreach($iconvEncodings as $encoding){
            try{
                iconv($encoding, 'UTF-8', $str);
                return $encoding;
            }
            catch (\Exception $exception){
                continue;
            }
        }
        return $finalEncoding;
    }
显然没有编码工作,所有的东西都给出了相同的例外。我假设问题在于通过guzzle正确检索响应json,而不是iconv本身。这不可能不是1000+中的任何一个

有关CURL的更多信息

我只是使用CURL重试了相同的负载

  /**
     * @param $options
     * @return bool|string
     */
    public function makeCurlRequest($options)
    {

        $payload = json_encode($options);
        // Prepare new cURL resource
        $ch = curl_init($this->softoneurl);

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,   // return web page
            CURLOPT_HEADER => false,  // don't return headers
            CURLOPT_FOLLOWLOCATION => true,   // follow redirects
            CURLOPT_MAXREDIRS => 10,     // stop after 10 redirects
            CURLOPT_ENCODING => "",     // handle compressed
            CURLOPT_USERAGENT => "test", // name of client
            CURLOPT_AUTOREFERER => true,   // set referrer on redirect
            CURLOPT_CONNECTTIMEOUT => 120,    // time-out on connect
            CURLOPT_TIMEOUT => 120,    // time-out on response
            CURLINFO_HEADER_OUT => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $payload,
        ]);

        // Set HTTP Header for POST request
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json',
                'Content-Length: ' . strlen($payload))
        );

        // Submit the POST request
        $result = curl_exec($ch);

        // Close cURL session handle
        curl_close($ch);
        return $result;
    }
我收到了完全相同的字符串和转换结果。也许我错过了一个选择

显然,iconv本身在环境中存在一些问题,并且不是特定于应用程序的。通过SSH运行以下代码

php -r "var_dump(iconv('Windows-1253', 'UTF-8', 'test'));"
屈服

PHP Notice:  iconv(): Wrong charset, conversion from `Windows-1253' to `UTF-8' is not allowed in Command line code on line 1
PHP Stack trace:
PHP   1. {main}() Command line code:0
PHP   2. iconv(*uninitialized*, *uninitialized*, *uninitialized*) Command line code:1
Command line code:1:
bool(false)
可能缺少某些依赖项

请尝试以下操作:

$response = $guzzle->request('GET', $url);

$type = $response->getHeader('content-type');
$parsed = Psr7\parse_header($type);

$original_body = (string)$response->getBody();
$utf8_body = mb_convert_encoding($original_body, 'UTF-8', $parsed[0]['charset'] ?: 'UTF-8');
试试这个:

$response = $guzzle->request('GET', $url);

$type = $response->getHeader('content-type');
$parsed = Psr7\parse_header($type);

$original_body = (string)$response->getBody();
$utf8_body = mb_convert_encoding($original_body, 'UTF-8', $parsed[0]['charset'] ?: 'UTF-8');

大约14个小时的故障排除之后,我能够正确回答我自己的问题。在我的例子中,由于这是在CLI命令的上下文中运行的,因此由于缺少库而导致了问题。基本上,CLI php二进制文件无法访问iconv所需的某些库

更具体地说,是gconv库。 在我的Debian 9中,它位于

/usr/lib/x86_64-linux-gnu/gconv

这个文件夹包含了很多库,用于每种编码。 理解这一点的一个好方法是,如果您在一个系统中运行,那么您拥有root用户访问该命令的权限

strace iconv-f-t utf-8


它将产生iconv尝试访问的许多文件夹,包括gconv文件夹,并将指向您需要包含在SSH环境中的文件夹的位置。如果您没有根用户权限,则必须询问您的主机提供商

大约14小时的故障排除之后,我能够正确回答自己的问题。在我的例子中,由于这是在CLI命令的上下文中运行的,因此由于缺少库而导致了问题。基本上,CLI php二进制文件无法访问iconv所需的某些库

更具体地说,是gconv库。 在我的Debian 9中,它位于

/usr/lib/x86_64-linux-gnu/gconv

这个文件夹包含了很多库,用于每种编码。 理解这一点的一个好方法是,如果您在一个系统中运行,那么您拥有root用户访问该命令的权限

strace iconv-f-t utf-8


它将产生iconv尝试访问的许多文件夹,包括gconv文件夹,并将指向您需要包含在SSH环境中的文件夹的位置。如果您没有根用户权限,则必须询问您的主机提供商

json\u last\u error\u msg()
返回什么?还有,编码是什么?你知道这不是UTF-8吗?我刚刚用我看到的更新了我的问题。非常混乱。Guzzle没有正确读取结果。
mb\u convert\u encoding()
不支持Windows-1253,但是
iconv()
应该可以正常工作。JSON必须编码为UTF-8(这不是可选的),因此您需要在使用JSON函数之前修复它。我建议你一次解决一件事。例如,将响应保存到一个文件,然后确定它是否实际使用Windows-1253,以及
iconv()
是否可以修复它。
json\u last\u error\u msg()
返回什么?还有,编码是什么?你知道这不是UTF-8吗?我刚刚用我看到的更新了我的问题。非常混乱。Guzzle没有正确读取结果。
mb\u convert\u encoding()
不支持Windows-1253,但是
iconv()
应该可以正常工作。JSON必须编码为UTF-8(这不是可选的),因此您需要在使用JSON函数之前修复它。我建议你一次解决一件事。例如,将响应保存到一个文件,然后确定它是否实际使用Windows-1253,以及
iconv()
是否可以修复它。我已经从guzzle存储库问题中尝试了这个确切的示例。结果和以前一样。我已经从guzzle存储库问题中尝试了这个确切的例子。结果和以前一样。