/ / String JSON (codificado de matriz grande) ficou truncado quando a saída para o cliente HTTP - php, json, codeigniter

String JSON (codificada de matriz grande) foi truncada quando a saída para o cliente HTTP - php, json, codeigniter

Eu encontrei um problema que a saída da cadeia JSON para o cliente HTTP foi truncada perto para fechar a tag.

Um exemplo,

uma. espere ver - ... ... "last_update": "2014-06-10 20:46:38", "garden_id": "1"}], "message": null}

b. na verdade é - ... ... "last_update": "2014-06-10 20:46:38", "garden_id": "1"}], "message": nul

Os dois últimos personagens foram truncados por algum motivo !!!

Eu tentei tanto Postman no Chrome e enrolar em umconsole, todos a mesma saída. Portanto, não parece um problema específico do navegador. A string JSON no meu aplicativo vem de um json_encode do PHP em um array associativo. O código PHP está usando a estrutura CodeIgniter em execução no Apache. Eu tentei escrever a cadeia json em um arquivo antes de saída http, o conteúdo do arquivo é 100% correto. Portanto, não é um problema de codificação json no PHP.

O PHP é bastante simples. Eu tenho construir abaixo da matriz (ou seja, $ finaldata) da consulta do banco de dados

{
"success": true,
"data": [
{
"file_id": "1",
"title": "xxx",
"create_date": "2014-05-18 21:30:19",
"auditor": "1",
"status": "1",
"last_updater": null,
"last_update": "2014-06-10 20:43:14",
"garden_id": "1"
},
{
"file_id": "2",
"title": "yyy",
"create_date": "2014-05-18 21:30:19",
"auditor": "1",
"status": "1",
"last_updater": null,
"last_update": "2014-06-10 20:43:14",
"garden_id": "1"
}
],
"message": null
}

o "data" tem um sub array e pode ser um array longo depende dos registros do banco de dados. Então a variável $ finaldata é passada para uma função de saída que tem abaixo da lógica geral:

header("Content-Type: ".$this->_supported_formats[$this->response->format]);
$output = $this->format->factory($finaldata)->{"to_".$this->response->format}();
header("Content-Length: " . strlen($output));

A função de saída é construída por uma biblioteca RESTful https://github.com/philsturgeon/codeigniter-restserver. Neste contexto, é igual a

header("Content-Type: Application/json");
$output = json_encode($finaldata);

Mas eu achei uma coisa interessante que a questãosó aconteceu se o tamanho da string exceder 8K. E quando eu adiciono uma string aleatória como "ZZZ" à string JSON antes da resposta HTTP, o problema desapareceu. Eu não sei o motivo por trás. Não é um hack correto porque eu não poderia provar 8K é um limite real embora.

Alguém já conheceu esse problema antes? Qualquer sugestão ou comentários são apreciados.

Respostas:

1 para resposta № 1

Eu acho que você envia os dados em utf-8 charset então tente mudar essas linhas

header("Content-Type: ".$this->_supported_formats[$this->response->format]);
header("Content-Length: " . strlen($output));

para este

header("Content-Type: ".$this->_supported_formats[$this->response->format] . "; charset=utf-8");
header("Content-Length: " . mb_strlen($output));

Se isso não funcionar, não envie o Content-Length cabeçalho em tudo. Este cabeçalho é "apenas útil" se você enviar um arquivo para o navegador (como um download).


0 para resposta № 2

No meu problema, eu habilito o gzip no nginx e adiciono application/json para o campo de gzip_types. Então, eu defino um cabeçalho quando faço uma solicitação com o Guzzle. Parece que

    if (! isset($parameters["headers"])) {
$parameters["headers"]["Accept-Encoding"] = "gzip";
}