json_encode está retornando NULL?

119

Por algum motivo, o item "descrição" retorna NULLcom o seguinte código:

<?php
include('db.php');

$result = mysql_query('SELECT * FROM `staff` ORDER BY `id` DESC LIMIT 2') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>

Aqui está o esquema para meu banco de dados:

CREATE TABLE `staff` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext COLLATE utf8_unicode_ci,
  `description` longtext COLLATE utf8_unicode_ci,
  `icon` longtext COLLATE utf8_unicode_ci,
  `date` longtext COLLATE utf8_unicode_ci,
  `company` longtext COLLATE utf8_unicode_ci,
  `companyurl` longtext COLLATE utf8_unicode_ci,
  `appurl` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Aqui está o que é ecoado na página:

[{"id":"4","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"},{"id":"3","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"}]

Alguma ideia?

Tarnfeld
fonte
Vamos colocar as chaves da matriz entre aspas, antes de tudo.
Joost
Você poderia fornecer informações sobre o esquema da sua tabela "equipe". Existe uma coluna chamada descrição?
28610 mopoke
todos esses campos ecoarão se eu simplesmente fizer um eco $r['description']fora da instrução for ()?
tarnfeld 28/12/2009
Ou talvez algum exemplo de conteúdo de $ r ['description'] ajude. Que tipo de dados é esse?
Mopoke
você poderia fazer uma captura de tela do banco de dados shema? ;-)
streetparade

Respostas:

256

Aposto que você está recuperando dados em codificação não utf8: tente colocar mysql_query('SET CHARACTER SET utf8')antes da sua SELECTconsulta.

ntd
fonte
5
oi, esta resposta salvou minha vida, obrigado. Eu estava tendo o mesmo problema aqui. Eu tinha valores com caracteres não utf8 como "Validação de Formulários". Eu sei que essa pergunta é um pouco antiga agora, mas essa é a grandiosidade da internet !!
Fabio11
7
mysql_set_charset é melhor por razões de segurança desde o PHP 5.2.3. Veja php.net/manual/en/function.mysql-set-charset.php para obter detalhes.
precisa saber é o seguinte
3
Porque UTF8 é a língua franca na web. Em vez de sobrecarregar a API com parâmetros adicionais e sobrecarga, o PHP (rigidamente) usa a codificação mais comum, deixando para você a carga de conversão se você usar uma codificação incomum (ou quase morta, como no seu caso).
Ntd
1
A maneira recomendada de fazer isso agora mudou. Tentei editar esta resposta para incluir um link, mas fui rejeitado. A maneira correta está na minha resposta abaixo.
bejs
1
@VeeK, não basta ter seus campos armazenados em UTF-8: você deve configurar seu servidor para responder aos clientes em UTF-8. O estoque AFAIK mysql e mariadb usam latin1.
ntd 31/12/17
118

Se você possui pelo menos o PHP 5.5, pode usar json_last_error_msg () , que retornará uma string descrevendo o problema.

Se você não possui o 5.5, mas está acima / 5.3, pode usar json_last_error () para ver qual é o problema.

Ele retornará um número inteiro, que você pode usar para identificar o problema na documentação da função . Atualmente (01.01.2012), os identificadores são:

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

Isso pode mudar em versões futuras, por isso é melhor consultar o manual.

Se você está abaixo de 5,3, está sem sorte, não há como perguntar qual foi o erro.

K. Norbert
fonte
18

A resposta do ntd não resolveu meu problema. Para aqueles na mesma situação, eis como eu finalmente lidei com esse erro: Apenas utf8_encode cada um dos seus resultados.

while($row = mysql_fetch_assoc($result)){
    $rows[] = array_map('utf8_encode', $row);
}

Espero que ajude!

Pablo Abdelhay
fonte
Eu também tive problemas de codificação. com codificação mista. solução que eu encontrei: stackoverflow.com/a/3521396/776345
Paschalis
9

alguns dias atrás eu tenho o mesmo problema com 1 tabela.

Primeiro tente:

echo json_encode($rows);
echo json_last_error();  // returns 5 ?

Se a última linha retornar 5, o problema está nos seus dados . Eu sei, suas tabelas estão em UTF-8, mas não inseriram dados . Por exemplo, a entrada estava no arquivo txt, mas foi criada na máquina Win com codificação estúpida (no meu caso, Win-1250 = CP1250) e esses dados foram inseridos no banco de dados.

Solução? Procure novos dados (excel, página da web), edite o arquivo txt de origem via PSPad (ou qualquer outra coisa), altere a codificação para UTF-8 , exclua todas as linhas e agora coloque os dados do original. Salve . Entre no DB .

Você também pode alterar a codificação apenas para utf-8 e, em seguida, alterar todas as linhas manualmente (dê às colunas caracteres especiais - desc, ...). Bom para escravos ...

Ivo Urbanek
fonte
ou use a JSON_PARTIAL_OUTPUT_ON_ERRORopção para ver o problema (por exemplo, o campo com UTF8 será nulo).
Peter Krauss
6

Você deve passar a string codificada utf8 em json_encode. Você pode usar utf8_encodee array_map()funcionar como abaixo:

<?php
    $encoded_rows = array_map('utf8_encode', $rows);
    echo json_encode($encoded_rows);
?>
koder
fonte
4

AHHH!!! Isso parece tão errado que machuca minha cabeça. Tente algo mais como este ...

<?php
include('db.php');

$result = mysql_query('SELECT `id`, `name`, `description`, `icon` FROM `staff` ORDER BY `id` DESC LIMIT 20') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>
  • Ao iterar sobre mysql_num_rowsvocê <não deve usar <=. Você também deve armazenar em cache esse valor (salve-o em uma variável) em vez de recontar cada loop. Quem sabe o que está fazendo sob o capô ... (pode ser eficiente, não tenho muita certeza)
  • Você não precisa copiar cada valor explicitamente assim ... você está apenas tornando isso mais difícil para si mesmo. Se a consulta estiver retornando mais valores do que você listou lá, liste apenas os que você deseja no seu SQL.
  • mysql_fetch_arrayretorna os valores por keye por int. Você não está usando os índices, então não os busque.

Se isso realmente é um problema json_encode, posso sugerir a substituição do corpo do loop por algo como

$rows[] = array_map('htmlentities',$row);

Perhpas, existem alguns caracteres especiais que estão sujando as coisas ...

mpen
fonte
[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / produtividade \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ / dbelement.com \ / "," appurl ":" http: \ / \ / noter2.dbelement.com "}, {" id ":" 3 "," nome ":" Noter 2 "," descrição ": nulo," ícone ":" http: \ / \ / images .apple.com \ / webapps \ / production \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com "
tarnfeld 28/12/2009
@tarnfield: Bem, é isso que você quer ou não? Oh ... você tem mais informações aqui ... aqui ... deixe-me consertar isso para você.
Md #
sim "descrição" retornanull
tarnfeld 28/12/2009
Se a descrição está retornando null, provavelmente está null . Tente echo $row['description'].'<br/>';nesse loop e veja o que diz.
Md #
1
oi, esta resposta salvou minha vida, obrigado. Eu estava tendo o mesmo problema aqui. Eu tinha valores com caracteres não utf8 como "Validação de Formulários". Eu sei que essa pergunta é um pouco antiga agora, mas essa é a grandiosidade da internet !!
Fabio
3

Para quem usa o DOP, a solução é semelhante à resposta do ntd .

Na página de construção PHP PDO :: __ , como um comentário do usuário Kiipa em live dot com :

Para obter o conjunto de caracteres UTF-8, você pode especificar isso no DSN.

$ link = novo PDO ("mysql: host = localhost; dbname = DB; charset = UTF8 ");

MichaelS
fonte
0

Para mim, um problema em que json_encode retornaria codificação nula de uma entidade foi porque minha implementação jsonSerialize buscou objetos inteiros para entidades relacionadas; Resolvi o problema, certificando-me de buscar o ID da entidade relacionada / associada e chamei -> toArray () quando havia mais de uma entidade associada ao objeto a ser serializado pelo json. Note, eu estou falando sobre casos em que um implements JsonSerializableem entidades.

Victor S
fonte
-4

Eu tive o mesmo problema e a solução foi usar minha própria função em vez de json_encode()

echo '["' . implode('","', $row) . '"]';
Laci
fonte