2009-10-14 16 views
29

Sto riscrivendo la nostra classe di database (basata su PDO) e mi sono bloccato. Mi è stato insegnato ad usare entrambi SET NAMES utf8 e SET CHARACTER SET utf8 quando si lavora con UTF-8 in PHP e MySQL.È necessario "SET CARACTER SET utf8"?

In PDO, ora desidero utilizzare il parametro PDO::MYSQL_ATTR_INIT_COMMAND, ma supporta solo una query.

È necessario SET CHARACTER SET utf8?

risposta

81

Utilizzando SET CHARACTER SET utf8 dopo aver usato SET NAMES utf8 effettivamente azzerare il character_set_connection e collation_connection-
@@character_set_database e @@collation_database rispettivamente.

Il manual afferma che

  • SET NAMES x è equivalente a

    SET character_set_client = x; 
    SET character_set_results = x; 
    SET character_set_connection = x; 
    
  • e SET CHARACTER SET x è equivalente a

    SET character_set_client = x; 
    SET character_set_results = x; 
    SET collation_connection = @@collation_database; 
    

mentre SET collation_connection = x esegue internamente anche SET character_set_connection = <<character_set_of_collation_x>> e SET character_set_connection = x internamente esegue anche SET collation_connection = <<default_collation_of_character_set_x.

Quindi in pratica si sta reimpostando character_set_connection a @@character_set_database e collation_connection a @@collation_database. Il manuale spiega l'utilizzo di queste variabili:

Quali set di caratteri dovrebbe server tradurre una dichiarazione dopo la riceverlo?

Per questo, il server utilizza le variabili character_set_connection e sistema collation_connection. Converte le istruzioni inviate dal client da character_set_client a character_set_connection (ad eccezione dei valori letterali stringa con un introduttore come _latin1 o _utf8). collation_connection è importante per i confronti di stringhe letterali. Per i confronti di stringhe con i valori della colonna , la collation_connection non è perché le colonne hanno le loro regole di confronto , che ha una precedenza di confronto maggiore .

Per riassumere questo, l'/ procedura transcodifica codifica MySQL utilizza per elaborare la query ei suoi risultati è un multi-step-cosa:

  1. MySQL per trattamento query entrante ad essere codificati in character_set_client.
  2. MySQL transcodifica la dichiarazione da character_set_client in character_set_connection
  3. quando si confrontano i valori delle stringhe di colonna di valori di MySQL transcodifica il valore della stringa da character_set_connection nel set di caratteri della colonna del database data e utilizza le regole di confronto della colonna di fare l'ordinamento e il confronto.
  4. MySQL costruisce il set di risultati codificato in character_set_results (questo include dati dei risultati e metadati risultato come nomi di colonna e così via)

quindi potrebbe essere il caso che un SET CHARACTER SET utf8 non sarebbe sufficiente a fornire supporto UTF-8 completo. Pensare a un set di caratteri del database predefinito di latin1 e colonne definite con utf8 -charset e seguire i passaggi sopra descritti. Come latin1 non può coprire tutti i personaggi che UTF-8 può coprire si rischia di perdere le informazioni di carattere al punto .

  • Passo : Dato che la query è codificato in UTF-8 e contiene caratteri che non possono essere rappresentati con latin1, questi personaggi saranno persi sulla transcodifica da utf8 al latin1 (il set di caratteri database predefinito) facendo fallire la tua ricerca.

Quindi penso che sia sicuro dire che SET NAMES ... è il modo corretto per gestire i problemi relativi ai set di caratteri. Anche se potrei aggiungere che l'impostazione corretta delle variabili del server MySQL (tutte le variabili richieste possono essere impostate staticamente nel tuo my.cnf) ti libera dal sovraccarico prestazionale della query aggiuntiva richiesta su ogni connessione.

+6

Wow, sono senza parole! Grazie! Ti meriti una stella d'oro :-) – Znarkus

+0

+1 Grazie per la vasta scrittura. Capisco come/quando il 3 dovrebbe essere usato. –

+0

Ottima, ottima, ottima risposta! – felipsmartins

2

Dal mysql manual:

set di caratteri SET è simile a SET nomi, ma imposta character_set_connection e collation_connection a character_set_database e collation_database. Una dichiarazione SET CHARACTER SET x è equivalente a questi tre affermazioni:

SET character_set_client = x; 
SET character_set_results = x; 
SET collation_connection = @@collation_database; 
0

Dal momento che la necessità di supportare set di caratteri internazionali, ho sempre e solo impostare il set il carattere dei campi di tipo testo sulla creazione del database.

Ho sempre utilizzato anche UTF-8.

All'interno PHP impostare lo stesso:

mb_internal_encoding('UTF-8'); 
+0

proposito: impostazione delle regole di confronto delle colonne del database non è sufficiente a fornire un supporto UTF-8. Ci sono molte altre cose tra il tuo script PHP e la colonna del database reale. –

+0

Grazie. Non sono mai stato morso da questo ancora. Buono a sapersi. –

Problemi correlati