IMPOSTARE NOMI utf8 in MySQL?


110

Vedo spesso qualcosa di simile a questo di seguito negli script PHP che utilizzano MySQL

query("SET NAMES utf8");   

Non ho mai dovuto farlo per nessun progetto, quindi ho un paio di domande di base a riguardo.

  1. È qualcosa che viene fatto solo con DOP?
  2. Se non è una cosa specifica DOP, qual è lo scopo di farlo? Mi rendo conto che sta impostando la codifica per mysql ma voglio dire, non ho mai dovuto usarlo, quindi perché dovrei usarlo?

4
"SET NAMES utf8" dovrebbe essere evitato a causa di SQL injection. Vedi php.net/manual/en/mysqlinfo.concepts.charset.php per i dettagli.
masakielastic

3
@masakielastic Non vedo dove l'impostazione di "set names utf8" è una minaccia per sql injection? Utilizzando l'API MySQL corretta dov'è il thread?
banda larga

3
Scusa per la mia scortesia. Vedi la risposta di ircmaxell : stackoverflow.com/a/12118602/531320 Althogh "SET NAMES" non ha problemi fintanto che si utilizza UTF-8, la possibilità di utilizzare GBK o Big5 (cinese) o Shift_JIS (giapponese) in futuro è innegabile .
masakielastic

Risposte:


74

È necessario ogni volta che si desidera inviare dati al server con caratteri che non possono essere rappresentati in ASCII puro, come "ñ" o "ö".

Che se l'istanza MySQL non è configurata per aspettarsi la codifica UTF-8 per impostazione predefinita dalle connessioni client (molte lo sono, a seconda della posizione e della piattaforma).

Leggi http://www.joelonsoftware.com/articles/Unicode.html se non sei a conoscenza di come funziona Unicode.

Leggi Se usare "SET NAMES" per vedere le alternative SET NAMES e di cosa si tratta esattamente.


3
'ö' e 'ñ' sono ASCII estesi. SET NAMES UTF8Ne avresti ancora bisogno per loro?
Tim

2
Ho scoperto che spesso devo aggiungere utf8_decode ($ my_text); in PHP per ottenere caratteri speciali UTF-8 da mostrare correttamente sui siti Web quando i dati sono stati richiesti da MySQL. Le mie tabelle e colonne sono impostate su UTF-8 in MySQL, quindi dovrebbe essere necessario?
NexusRex

1
@ Vinko Vrsalovic: Non necessariamente ... avevo tutti i miei file in utf8 ma il mio precedente hoster aveva il set di caratteri mysql impostato su latin1 e poiché non ho detto a mysql che sto inviando caratteri in utf8 (quindi impostare i nomi utf8) li ha memorizzati in caratteri latini e tutti i miei caratteri speciali (čšž sloveno) sembravano essere stati invasi da un'auto - ancora una cosa: quando fai una ricerca in phpmyadmin non troverai risultati, perché una č è come Å e così via
Erik Čerpnjak

Si noti che specifica anche il set di caratteri che il server dovrebbe utilizzare per inviare i risultati al client, quindi è necessario anche quando si ricevono questi dati, utilizzando ad esempio SELECTun'istruzione.
Leopoldo Sanczyk

@ Tim. Non esiste davvero una cosa come "ASCII esteso". Ci sono un sacco di codifiche diverse che possono essere chiamate ASCII estese (qualsiasi set di caratteri a byte singolo in cui la prima metà è uguale a ASCII, e ce ne sono un sacco).
TRiG

43

Dal manuale :

SET NAMES indica quale set di caratteri il client utilizzerà per inviare istruzioni SQL al server.

Più elaboratamente, (e ancora una volta, gratuitamente sollevato dal manuale ):

SET NAMES indica quale set di caratteri il client utilizzerà per inviare istruzioni SQL al server. Pertanto, SET NAMES 'cp1251' dice al server, "i futuri messaggi in arrivo da questo client sono nel set di caratteri cp1251". Specifica inoltre il set di caratteri che il server deve utilizzare per inviare i risultati al client. (Ad esempio, indica quale set di caratteri utilizzare per i valori di colonna se si utilizza un'istruzione SELECT.)


6
Ti amo. Ho appena fatto la mia serata!
karim79

34

Ottenere la codifica corretta è davvero complicato: ci sono troppi livelli:

  • Browser
  • Pagina
  • PHP
  • MySQL

Il comando SQL "SET CHARSET utf8" da PHP assicurerà che il lato client (PHP) riceva i dati in utf8, indipendentemente da come sono memorizzati nel database. Ovviamente, prima devono essere conservati correttamente.

Definizione DDL e dati reali

La codifica definita per una tabella / colonna non significa realmente che i dati siano in quella codifica. Se ti è capitato di avere una tabella definita come utf8ma memorizzata come codifica diversa, MySQL la tratterà come se fosse utf8e sei nei guai. Il che significa che devi prima risolvere questo problema.

Cosa controllare

È necessario controllare cosa codifica il flusso di dati a ogni livello.

  • Controlla intestazioni HTTP, intestazioni.
  • Controlla cosa è realmente inviato nel corpo della richiesta.
  • Non dimenticare che MySQL ha la codifica quasi ovunque:
    • Banca dati
    • tabelle
    • colonne
    • Server nel suo insieme
    • Cliente
      Assicurati che ci sia quello giusto ovunque.

Conversione

Se si ricevono dati ad es windows-1250. E si desidera archiviarli utf-8, utilizzare questo SQL prima di archiviare:

SET NAMES 'cp1250';

Se hai dati nel DB come windows-1250e vuoi recuperarli utf8, usa:

SET CHARSET 'utf8';

Poche altre note:

  • Non fare affidamento su strumenti troppo "intelligenti" per mostrare i dati. Ad esempio phpMyAdmin fa (stava facendo quando lo stavo usando) la codifica davvero male. E passa attraverso tutti gli strati, quindi è difficile scoprirlo.
  • Inoltre, Internet Explorer aveva un comportamento davvero stupido di "indovinare" la codifica in base a regole strane.
  • Usa semplici editor in cui puoi cambiare la codifica. Raccomando MySQL Workbench.

19

Questa query dovrebbe essere scritta prima della query che crea o aggiorna i dati nel database, questa query ha il seguente aspetto:

mysql_query("set names 'utf8'");

Nota che dovresti scrivere la codifica che stai usando nell'intestazione per esempio se stai usando utf-8 lo aggiungi in questo modo nell'intestazione o causerà un problema con Internet Explorer

quindi la tua pagina avrà questo aspetto

<html>
    <head>
        <title>page title</title>
        <meta charset="UTF-8" />   
    </head>
    <body>
    <?php
            mysql_query("set names 'utf8'");   
            $sql = "INSERT * FROM ..... ";  
            mysql_query($sql);
    ?>    

    </body>
</html>

8
Non dovresti usare la libreria PHP mysql invece dovresti usare MySQLi o PDO.
André Figueira

Ottima risposta, grazie per l'esempio. Questa è l'unica risposta che mi ha aiutato a visualizzare ciò che dovevo fare e ha risolto il mio problema!
GTS Joe,

1
L'ultimo tag dovrebbe essere </html> non <html>
GTS Joe

9

La soluzione è

 $conn->set_charset("utf8");

5

Invece di farlo tramite una query SQL, usa la funzione php: mysqli :: set_charset mysqli_set_charset

Note:

This is the preferred way to change the charset. Using mysqli_query() to set it (such as SET NAMES utf8) is not recommended.

Vedere la sezione Concetti sui set di caratteri MySQL per ulteriori informazioni.

da http://www.php.net/manual/en/mysqli.set-charset.php


1

Ringrazia tutti!

non usare: query ("SET NAMES utf8"); questa è roba di configurazione e non una query. rimettilo a posto dopo una connessione inizia con setCharset () (o un metodo simile)

qualche piccola cosa in parctice:

stato:

  • Il server mysql di default parla latin1
  • la tua app hole è in utf8
  • la connessione viene effettuata senza alcun extra (quindi: latin1) (no SET NAMES utf8 ..., no set_charset () metodo / funzione)

Archiviare e leggere i dati non è un problema finché mysql può gestire i caratteri. se guardi nel db vedrai già che c'è una schifezza (ad esempio usando phpmyadmin).

fino ad ora questo non è un problema! (sbagliato ma funziona spesso (in europa)) ..

..a meno che un altro client / programma o una libreria modificata, che funziona correttamente, leggerà / salverà i dati. allora sei in grossi guai!


0

Non solo DOP. Se sql rispondi come "????" simboli, preimpostati del tuo set di caratteri (spero UTF-8) davvero consigliati:

if (!$mysqli->set_charset("utf8")) 
 { printf("Can't set utf8: %s\n", $mysqli->error); }

o tramite lo stile della procedura mysqli_set_charset($db,"utf8")

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.