2012-04-18 10 views
54

Sto chiamando json_encode() su dati che provengono da un database MySQL con fascicolazione utf8_general_ci. Il problema è che alcune righe hanno dati strani che non riesco a pulire. Ad esempio il simbolo , quindi, una volta raggiunto json_encode(), non riesce con json_encode(): Invalid UTF-8 sequence in argument.json_encode(): sequenza UTF-8 non valida nell'argomento

Ho provato utf8_encode() e utf8_decode(), anche con mb_check_encoding() ma continua a subire e causare caos.

Esecuzione di PHP 5.3.10 su Mac. Quindi la domanda è: come posso ripulire i simboli utf8 non validi, mantenendo il resto dei dati, in modo che json_encoding() funzioni?

Aggiornamento

. Ecco un modo per riprodurlo:

echo json_encode(pack("H*" ,'c32e')); 
+0

Sei sicuro di voler recuperare i dati codificati in UTF-8 dal database? Che dati hai, cosa ti aspetti? Mostraci un 'bin2hex' dei dati problematici. – deceze

+0

bin2hex fornisce c32e –

+0

'" \ xC3 \ x2E "' non è una stringa UTF-8 valida. da dove viene? MySQL non deve produrre stringhe UTF-8 non valide se è impostato per restituire UTF-8. – deceze

risposta

23

Sembra che il simbolo era Å, ma dal momento che i dati si compone di cognomi che non dovrebbero essere pubblici, solo la prima lettera è stato mostrato e è stato fatto da solo $lastname[0], che è sbagliato per le stringhe multibyte e ha causato l'intera seccatura. Modificato su mb_substr($lastname, 0, 1) - funziona come un fascino.

+0

Mi sono appena imbattuto nello stesso problema; risulta che ho avuto una chiamata a 'substr()' simile al tuo '[0]' dereference ;-) –

+0

Inoltre, questo errore può essere lanciato su json_encode dopo preg_replace da regexp senza il modificatore 'u'. – rNix

2

Il simbolo che hai postato è il simbolo del segnaposto per una sequenza di byte spezzata. Fondamentalmente, non è un vero simbolo ma un errore nella tua stringa.

Qual è il valore byte esatto del simbolo? Applicare ciecamente utf8_encode non è una buona idea, è meglio scoprire prima da dove viene il byte (s) e cosa significano.

+0

Dubito che riesca a risalire a dove quel simbolo è venuto da –

+0

Potrebbe essere possibile salvarlo con il set di caratteri sbagliato. Devi sempre assicurarti di CONOSCERE il set di caratteri di tutte le tue stringhe in modo da non averle mai nemmeno torto. Ora è necessario scoprire quali stringhe sono salvate nel set di caratteri sbagliato e trovare un modo per convertirle in quella corretta, o eventualmente eliminare le stringhe non valide. Potrebbe non essere sempre possibile convertire le stringhe poiché potresti aver perso dei byte lungo la strada se hai lavorato con le codifiche miste. –

+0

bene se non riesci a scoprire perché quel simbolo è lì dentro, quindi prova a pubblicare * quale * simbolo è. Il segnaposto grafico non aggiunge molte informazioni :) – Evert

12

Assicurarsi che il set di caratteri di connessione a MySQL sia UTF-8. Spesso è impostato su ISO-8859-1, il che significa che il driver MySQL convertirà il testo in ISO-8859-1.

È possibile impostare il set di caratteri connessione con mysql_set_charset, mysqli_set_charset o con la query SET NAMES 'utf-8'

+0

SET NAMES viene chiamato, altri dati arrivano bene –

31

Ho avuto un errore simile che ha causato a json_encode di restituire un campo null ogni volta che c'era un carattere hi-ascii come un apostrofo ricurvo in una stringa, a causa del set di caratteri errato restituito nella query.

La soluzione era quella di assicurarsi che si presenta come utf8 aggiungendo:

mysql_set_charset('utf8'); 

dopo il mysql collegare dichiarazione.

+13

o 'mysqli_set_charset ($ con," utf8 ");' con mysqli. Grazie! – pmrotule

+0

funziona, grazie. – abhi

+0

o set di caratteri = utf8; nella tua stringa di connessione per PDO – jordan314

21

Il problema è che questo carattere è UTF8, ma json_encode non lo gestisce correttamente. Per aggiungere altro, c'è un elenco di altri caratteri (vedi Unicode characters list), che attiverà lo stesso errore, quindi rimuovere questo (Å) non risolverà un problema fino alla fine.

Ciò che abbiamo utilizzato è quello di convertire questi caratteri in html entità in questo modo:

htmlentities((string) $value, ENT_QUOTES, 'utf-8', FALSE); 
+0

ha funzionato bene qui. Grazie! – Fabiano

+0

come si userebbe questo se si sta codificando un array/stdClass – chiliNUT

+0

passare attraverso ogni proprietà di elemento/oggetto dell'array e chiamare questo metodo, ma, potrebbero esserci problemi di prestazioni con grandi array/oggetti –

0

Un'altra cosa che getta questo errore, quando si utilizza la funzione json_encode di PHP, è quando i caratteri Unicode sono maiuscole \ U e not lower case \ u

-1

Utilizzo di setLocale ('fr_FR.UTF8') prima che json_encode risolva il problema.

0

json_encode funziona solo con dati UTF-8. Dovrai assicurarti che i tuoi dati siano in UTF-8.in alternativa, è possibile utilizzare iconv() per convertire i risultati in UTF-8 prima di inviarli a json_encode()

5

L'utilizzo di questo codice può essere d'aiuto. Ha risolto il mio problema!

mb_convert_encoding($post["post"],'UTF-8','UTF-8'); 

o come quello

mb_convert_encoding($string,'UTF-8','UTF-8'); 
+0

grazie, ha fatto per me! – InsOp

+0

ha funzionato per me, yay! – gilm

0

Aggiornato .. Ho risolto questo problema indicando il charset sulla connessione PDO come di seguito:

"mysql: host = $ host; dbname = $ db ; charset = utf8"

Tutti i dati ricevuti era allora nel corretto set di caratteri per il resto del codice per utilizzare

0
I am very late but if some one working on SLIM to make rest api and getting same error can solve this problem by adding below line as: 

<?php 

// DbConnect.php file 
class DbConnect 
{ 
    //Variable to store database link 
    private $con; 

    //Class constructor 
    function __construct() 
    { 

    } 

    //This method will connect to the database 
    function connect() 
    { 
     //Including the constants.php file to get the database constants 
     include_once dirname(__FILE__) . '/Constants.php'; 

     //connecting to mysql database 
     $this->con = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME); 

     mysqli_set_charset($this->con, "utf8"); // add this line 
     //Checking if any error occured while connecting 
     if (mysqli_connect_errno()) { 
      echo "Failed to connect to MySQL: " . mysqli_connect_error(); 
     } 

     //finally returning the connection link 
     return $this->con; 
    } 
} 
Problemi correlati