json_encode sta restituendo NULL?


119

Per qualche motivo la "descrizione" dell'articolo ritorna NULLcon il seguente codice:

<?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);
?>

Ecco lo schema per il mio database:

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

Ecco cosa riecheggia nella pagina:

[{"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"}]

Qualche idea?


Mettiamo le chiavi dell'array tra virgolette, prima di tutto.
Joost

Potresti fornire informazioni sullo schema della tua tabella "staff". C'è una colonna chiamata descrizione?
mopoke

tutti questi campi risuoneranno se faccio semplicemente un eco $r['description']fuori dall'istruzione for ()?
tarnfeld

O forse qualche contenuto di esempio da $ r ['descrizione'] potrebbe aiutare. Di che tipo di dati si tratta?
mopoke

potresti fare uno screenshot del database shema? ;-)
streetparade

Risposte:


256

Scommetto che stai recuperando dati in codifica non utf8: prova a mettere mysql_query('SET CHARACTER SET utf8')prima la tua SELECTquery.


5
ciao, questa risposta mi ha salvato la vita, grazie. Ho avuto lo stesso problema qui. Avevo valori con caratteri non utf8 come "Validação de Formulários". So che questa domanda è un po 'vecchia ora, ma questa è la bellezza di Internet !!
fabio

7
mysql_set_charset è migliore per motivi di sicurezza da PHP 5.2.3. Vedi php.net/manual/en/function.mysql-set-charset.php per i dettagli.
masakielastic

3
Perché UTF8 è la lingua franca sul web. Invece di ingombrare l'API con parametri aggiuntivi e overhead, PHP (rigorosamente) utilizza la codifica più comune, lasciando a te l'onere della conversione se usi una codifica non comune (o quasi morta, come nel tuo caso).
ntd

1
Il modo consigliato per farlo è ora cambiato. Ho provato a modificare questa risposta per includere un collegamento ma è stato rifiutato. Il modo corretto è nella mia risposta di seguito.
bejs

1
@VeeK non è sufficiente che i tuoi campi siano memorizzati in UTF-8: devi configurare il tuo server per rispondere ai client in UTF-8. AFAIK, mysql e mariadb utilizzano latin1.
ntd

118

Se hai almeno PHP 5.5, puoi usare json_last_error_msg () , che restituirà una stringa che descrive il problema.

Se non hai 5.5, ma sei su / sopra 5.3, puoi usare json_last_error () per vedere qual è il problema.

Restituirà un numero intero, che puoi utilizzare per identificare il problema nella documentazione della funzione . Attualmente (2012.01.19), gli identificatori sono:

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

Questi possono cambiare nelle versioni future, quindi è meglio consultare il manuale.

Se sei sotto 5.3, sei sfortunato, non c'è modo di chiedere quale sia stato l'errore.


18

La risposta di ntd non ha risolto il mio problema. Per quelli nella stessa situazione, ecco come ho finalmente gestito questo errore: solo utf8_encode ciascuno dei tuoi risultati.

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

Spero che sia d'aiuto!


Ho avuto anche problemi di codifica. con codifica mista. soluzione che ho trovato: stackoverflow.com/a/3521396/776345
Paschalis

9

qualche giorno fa ho lo STESSO problema con 1 tavolo.

Innanzitutto prova:

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

Se l'ultima riga restituisce 5, il problema riguarda i tuoi dati . Lo so, le tue tabelle sono in UTF-8, ma non i dati inseriti . Ad esempio l'input era in file txt, ma creato su macchina Win con codifica stupida (nel mio caso Win-1250 = CP1250) e questi dati sono stati inseriti nel DB.

Soluzione? Cerca nuovi dati (excel, pagina web), modifica il file txt di origine tramite PSPad (o qualsiasi altra cosa), modifica la codifica in UTF-8 , elimina tutte le righe e ora metti i dati dall'originale. Salva. Entra in DB .

Puoi anche cambiare la codifica solo in utf-8 e quindi cambiare tutte le righe manualmente (dai cols con caratteri speciali - desc, ...). Buono per gli schiavi ...


oppure usa l' JSON_PARTIAL_OUTPUT_ON_ERRORopzione per vedere il problema (es. il campo con UTF8 sarà nullo).
Peter Krauss

6

Dovresti passare la stringa codificata utf8 in json_encode. Puoi usare utf8_encodee array_map()funzionare come di seguito:

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

4

AHHH !!! Sembra così sbagliato che mi fa male la testa. Prova qualcosa di più come questo ...

<?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);
?>
  • Durante l'iterazione mysql_num_rowsdovresti usare <not <=. Dovresti anche memorizzare questo valore nella cache (salvarlo in una variabile) invece di doverlo riconteggiare ad ogni ciclo. Chissà cosa sta facendo sotto il cofano ... (potrebbe essere efficiente, non ne sono proprio sicuro)
  • Non è necessario copiare ogni valore esplicitamente in questo modo ... lo stai solo rendendo più difficile per te stesso. Se la query restituisce più valori di quelli che hai elencato, elenca solo quelli che desideri nel tuo SQL.
  • mysql_fetch_arrayrestituisce i valori sia di keyche di int. Non stai usando gli indici, quindi non recuperarli.

Se questo è davvero un problema con json_encode, allora potrei suggerire di sostituire il corpo del loop con qualcosa di simile

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

Forse ci sono alcuni caratteri speciali che stanno facendo confusione ...


[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / produttività \ / 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 \ / produttività \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," azienda ":" dBelement, LLC "," companyurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"
Tarnfeld

@tarnfield: Beh, è ​​quello che vuoi o no? Oh ... hai alcune informazioni aggiuntive lì ... qui ... lascia che lo aggiusti per te.
mpen

sì "descrizione" ritornanull
tarnfeld

Se la descrizione sta tornando null, probabilmente lo è null . Prova echo $row['description'].'<br/>';in quel ciclo e guarda cosa dice.
mpen

1
ciao, questa risposta mi ha salvato la vita, grazie. Ho avuto lo stesso problema qui. Avevo valori con caratteri non utf8 come "Validação de Formulários". So che questa domanda è un po 'vecchia ora, ma questa è la bellezza di Internet !!
fabio


3

Per chiunque utilizzi PDO, la soluzione è simile alla risposta di ntd .

Dalla pagina PHP PDO :: __ build , come commento dell'utente Kiipa su live dot com :

Per ottenere il set di caratteri UTF-8 è possibile specificarlo nel DSN.

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


0

Per me, un problema in cui json_encode restituiva la codifica nulla di un'entità era perché la mia implementazione jsonSerialize recuperava interi oggetti per entità correlate; Ho risolto il problema assicurandomi di aver recuperato l'ID dell'entità correlata / associata e chiamato -> toArray () quando c'erano più entità associate all'oggetto da serializzare json. Nota, sto parlando di casi in cui uno implements JsonSerializablesu entità.


-4

Ho avuto lo stesso problema e la soluzione è stata quella di utilizzare la mia funzione invece di json_encode()

echo '["' . implode('","', $row) . '"]';
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.