{"id":211,"date":"2012-04-25T19:22:11","date_gmt":"2012-04-25T17:22:11","guid":{"rendered":"http:\/\/localhost\/blog\/?p=211"},"modified":"2012-12-29T20:05:42","modified_gmt":"2012-12-29T19:05:42","slug":"tutorial-occhio-al-charset","status":"publish","type":"post","link":"https:\/\/www.ilbytecidio.it\/?p=211","title":{"rendered":"Tutorial: occhio al charset!"},"content":{"rendered":"<p>Le diverse codifiche di caratteri causano grattacapi dall&#8217;alba dei tempi, ma ne sanno qualcosa soprattutto gli sviluppatori WEB, quando trovano strani simboli al posto delle lettere accentate!<!--more--><\/p>\n<p>Iniziamo dal principio. Perch\u00e9 i caratteri (numeri, lettere e simboli) che utilizziamo tutti i giorni sui nostri computer possano essere memorizzati e trasmessi devono essere codificati in modo numerico. L&#8217;associazione fra ciascun carattere e il numero che lo identifica si chiama charset o codifica dei caratteri. Per esempio, alla lettere A pu\u00f2 corrispondere il numero 65, alla B il numero 66 e cos\u00ec via.<\/p>\n<p>Fin qui niente di complicato, no?<br \/>\nNo! Perch\u00e9 purtroppo di codifica non ce n&#8217;\u00e8 una sola. Troverete tanti approfondimenti online, se siete curiosi. La <a href=\"http:\/\/it.wikipedia.org\/wiki\/Charset\">pagina su Wikipedia<\/a> offre una buona panoramica.<br \/>\nNon esiste uno standard? &#8211; chiederete voi. La risposta \u00e8 s\u00ec, ed il problema \u00e8 proprio l&#8217;opposto: ci sono tanti standard che possono essere utilizzati e la maggior parte dei software che vi servono (Server Web, DBMS, editor di testo) ne supportano pi\u00f9 di uno, ma quando questi software non sono d&#8217;accordo fra loro, succedono disastri, come le lettere accentate che spariscono e questo \u00e8 il meno perch\u00e9 in altri contesti potremmo andare incontro a perdita d&#8217;informazione o malfunzionamenti nei programmi! Del resto immaginate di dover decifrare un messaggio con una tabella dei codici sbagliata, non \u00e8 possibile!<br \/>\nNon ci addentriamo in troppi dettagli. Vi basti sapere che per i siti Web utilizziamo pi\u00f9 comunemente due codifiche standard: ISO-8859-1 e UTF-8. Il primo \u00e8 un set di caratteri che comprende i simboli utilizzati in Europa Occidentale ed il secondo \u00e8 una codifica Unicode, un sistema che mira a includere pi\u00f9 caratteri possibile fra quelli utilizzati nel mondo.<\/p>\n<p>Vediamo ora come mettere d&#8217;accordo i nostri programmi in modo da avere risultati puliti, senza fare casino con i caratteri speciali!<br \/>\nLa codifica standard per HTML \u00e8 l&#8217;ISO-8859-1, mentre per XML \u00e8 UTF-8. Come se non bastasse l&#8217;ISO-8859-1 non comprende simboli come \u20ac, \u0160, \u0161, \u017d, \u017e, che sono stati aggiunti con la codifica ISO-8859-15, spesso preferita alla precedente per questa ragione.<br \/>\nOra, dato che UTF-8 presenta indubbi vantaggi, primo assoluto il fatto di consentire l&#8217;utilizzo di tutti i caratteri che possono servirci &#8211; o potrebbero in futuro &#8211; mediante la stessa codifica, questo tutorial si baser\u00e0 su questo standard. Fra l&#8217;altro, sta lentamente soppiantando le altre codifiche, quindi lo considero un passo verso uno standard definitivo. Questa guida in effetti \u00e8 stata ispirata dal recente cambiamento introdotto in PHP 5.4 nelle funzioni htmlspecialchars ed htmlentities, che fino alla precedente versione assumevano di default la codifica ISO-8859-1 ed ora UTF-8. Il cambiamento non \u00e8 roba da poco, dato che queste funzioni sono largamente utilizzate e io stesso ho avuto un bel da fare per aggiornare del codice preesistente.<\/p>\n<p>Immaginiamo di creare un sito in PHP con database MySQL. Forse altri linguaggi, altri tool ed altre situazioni possono rendere superflua questa guida, ma i principi sono sempre utili.<\/p>\n<p><strong>Database<\/strong><br \/>\nPer prima cosa creeremo il database. Se usiamo phpmyadmin possiamo scegliere la &#8220;collation&#8221; per il database da un menu a tendina. A questo proposito, la collation complica ulteriormente il discorso sugli standard. Come apprendiamo dal <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.0\/en\/charset-general.html\">manuale di MySQL<\/a>, una collation \u00e8 un set di regole per la comparazione di caratteri all&#8217;interno di un set. Il discorso non \u00e8 banale e la scelta della collation va fatta in base alle sue qualit\u00e0 rispetto a quelle che ci servono. Ogni utente \u00e8 invitato a leggere la documentazione del DBMS che intende usare. Nel frattempo, possiamo usare utf8_unicode_ci che per un uso generale va pi\u00f9 che bene. Ovviamente quando scegliamo la collation abbiamo automaticamente scelto il set di caratteri a cui si riferisce. Se volessimo usare ISO-8859-15 potremmo scegliere latin1_swedish_ci.<br \/>\nLa query per la creazione del database sar\u00e0<\/p>\n<div>\n<blockquote>\n<div><code>CREATE DATABASE nome_db DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;<\/code><\/div>\n<\/blockquote>\n<\/div>\n<p>Da questo momento le tabelle create all&#8217;interno di questo DB ed i loro campi useranno di default il charset impostato. In ogni caso \u00e8 possibile specificare charset e collation per ogni tabella e per ogni suo campo di testo, vi rimando al manuale di MySQL per affrofondimenti.<\/p>\n<p><strong>Formato dei file<\/strong><br \/>\nOra \u00e8 il momento di pensare alla pagina Web che user\u00e0 il nostro database. Per iniziare, \u00e8 molto importante che la codifica del file che creiamo sia coerente con quella che vogliamo dare al nostro sito, altrimenti sulla pagina non avremmo i risultati sperati. Tutti gli editor seri consentono di scegliere la codifica col quale salvare il file. Se intendete creare le vostre pagine senza usare un IDE in particolare ma solo un editor di testo, vi consiglio Notepad++ per Windows, mentre su Linux dovrebbe andar bene anche quello della vostra distribuzione. Sia gedit che kwrite o kate hanno questa possibilit\u00e0. Su alcuni si sceglie la codifica quando si salva, su altri da subito. In quest&#8217;ultimo caso fatelo prima di iniziare se non volete che i caratteri speciali siano distorti. Scegliete UTF-8 e se il programma consente anche questa scelta, impostatelo perch\u00e9 non inserisca il BOM nel file. Si tratta di un codice che indica il formato del file, ma non \u00e8 indicato sui siti Web perch\u00e9 potrebbe comparire sul browser come carattere sconosciuto e dare problemi con PHP.<\/p>\n<p><strong>Indicazione del charset nella pagina<\/strong><br \/>\nCome accennato prima, ogni linguaggio ed ogni protocollo hanno dei charset di default, ma anche se si \u00e8 sicuri di usare quelli, \u00e8 buona abitudine specificarli per migliore chiarezza, e per evitare di incappare in impostazioni diverse.. insomma, per garantire l&#8217;interoperabilit\u00e0! Per quanto riguarda la nostra pagina, non potrebbe essere pi\u00f9 semplice. Inseriamo all&#8217;interno del tag head il seguente tag:<\/p>\n<div>\n<blockquote>\n<div><code>&lt;meta http-equiv=\"Content-Type\" content=\"text\/html; charset=utf-8\" \/&gt;<\/code><\/div>\n<\/blockquote>\n<\/div>\n<p>Questo tag aggiunge informazioni invisibili all&#8217;utente ma molto utili al browser per la corretta interpretazione della pagina. Innanzitutto specifica che il file \u00e8 un documento di testo che contiene direttive in linguaggio html e poi ovviamente aggiunge che la codifica \u00e8 UTF-8.<\/p>\n<p><strong>Charset della connessione al database<\/strong><br \/>\nL&#8217;ultimo sforzo \u00e8 quello di far s\u00ec che il charset usato dal DBMS per comunicare con la nostra applicazione sia lo stesso che intendiamo usare noi al suo interno. Anche in questo caso c&#8217;\u00e8 un default ma dipende dalla nostra particolare configurazione ed \u00e8 bene specificare il charset esplicitamente in modo che la nostra pagina giri su qualsiasi server, senza vincoli di impostazioni.<br \/>\nIl modo in cui eseguiamo questo passaggio dipende dalle librerie che utilizziamo.<br \/>\nSe usiamo la classica estensione mysql di PHP, subito dopo la chiamata a mysql_connect, possiamo inserire l&#8217;istruzione<\/p>\n<div>\n<blockquote>\n<div><code>mysql_set_charset('utf8');<\/code><\/div>\n<\/blockquote>\n<div><\/div>\n<div>oppure<\/div>\n<\/div>\n<div>\n<blockquote>\n<div><code>mysql_query('SET NAMES \"utf8\"');<\/code><\/div>\n<\/blockquote>\n<div><\/div>\n<div>Per entrambe \u00e8 possibile specificare l&#8217;ID della connessione, se serve, come secondo parametro.<\/div>\n<\/div>\n<p><strong>Attenzione!<\/strong><br \/>\nIl charset scelto potrebbe usare pi\u00f9 di un byte per codificare il singolo carattere. UTF-8 per esempio codifica i caratteri in modo variabile, da 1 a 4 byte. Questo si riflette soprattutto nella manipolazione di stringhe. Se per esempio chiamate la funzione strlen(&#8216;\u00c8&#8217;) nel vostro file codificato in UTF-8 noterete che il risultato \u00e8 2 e non 1 come potevate aspettarvi! Fortunatamente in PHP abbiamo a disposizione l&#8217;estensione mbstring (MultiByte String) che consente di eseguire le normali operazioni sulle stringhe in qualsiasi codifica. Inseriamo in testa alla nostra pagina<\/p>\n<div>\n<blockquote>\n<div><code>&lt;?php<br \/>\nheader(\"Content-type: text\/html; charset=UTF-8\");<br \/>\nmb_internal_encoding('UTF-8');<br \/>\n?php&gt;<\/code><\/div>\n<\/blockquote>\n<div><\/div>\n<div>Ora se chiamiamo la funzione mb_strlen(&#8216;\u00c8&#8217;) avremo 1 come ci aspettiamo!<\/div>\n<\/div>\n<p><strong>Migrare un sito preesistente?<\/strong><br \/>\nCi sono tanti sostenitori del passaggio a UTF-8 &#8220;perch\u00e9 sarebbe meglio&#8221;. Secondo me non esiste una ragione a priori. Qualche anno fa trovavamo ISO-8859-15 di default un po&#8217; ovunque, mentre oggi lo standard de facto sta diventando UTF-8. Potremmo decidere di adeguare il nostro sito oppure no, se ci conviene, ma un normale sito in italiano o al pi\u00f9 italiano\/inglese non ne ha molto bisogno. Comunque, l&#8217;operazione non \u00e8 banale e dobbiamo fare attenzione che ci\u00f2 che facciamo non comporti di rovinare il lavoro gi\u00e0 fatto. Meglio fare una copia del sito e dell&#8217;eventuale database prima di iniziare. Per prima cosa dovremmo convertire i file delle nostre pagine. Notepad++ ha un&#8217;opzione apposta per convertire un file di testo in UTF-8 e possiamo ottenere lo stesso anche con KWrite. Occorrer\u00e0 fare qualche prova per assicurarsi che tutto si conservi correttamente. Dopodich\u00e9 dovremmo aggiornare i meta tag nelle nostre pagine. La parte pi\u00f9 delicata \u00e8 il database, dato che probabilmente avremo tanti dati al suo interno. Vi consiglio di leggere <a href=\"http:\/\/www.zulutown.com\/blog\/2009\/02\/04\/migrate-mysql-database-from-latin1-to-utf8\/\">questo articolo<\/a>. Io ho semplicemente cambiato collation al database ed ai suoi campi ed i testi sono stati preservati senza problemi. Ovviamente non potremo mai migrare un testo in UTF-8 con caratteri giapponesi in ISO-8859-15 perch\u00e9 quest&#8217;ultimo non ha i simboli che ci servono, questo dovrebbe essere ovvio! Servir\u00e0 anche una revisione del codice per assicurarci di usare correttamente le funzioni di manipolazione delle stringhe, quindi a questo punto forse vale il buon vecchio principio di non toccare ci\u00f2 che funziona. Se non fosse per quel cambiamento introdotto da PHP non mi sarebbe mai venuto nemmeno in mente di mettervi in testa un&#8217;idea simile!<\/p>\n<p><strong>\u00c8 tutto<\/strong><br \/>\nSpero che questo tutorial serva a rendere le idee pi\u00f9 chiare su quest&#8217;aspetto che sembra pi\u00f9 complicato in apparenza di quanto non sia. L&#8217;importante \u00e8 tenere a mente tutte le regole di coerenza spiegate e controllare la documentazione riguardo alle funzioni che usiamo per manipolare le stringhe per assicurarci che non si aspettino un charset differente. Ricordate anche di chiedervi come avviene un&#8217;eventuale comunicazione fra il vostro codice ed altre applicazioni: potreste trovarvi a dover applicare le stesse regole anche in quei casi!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le diverse codifiche di caratteri causano grattacapi dall&#8217;alba dei tempi, ma ne sanno qualcosa soprattutto gli sviluppatori WEB, quando trovano strani simboli al posto delle lettere accentate!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[],"class_list":["post-211","post","type-post","status-publish","format-standard","hentry","category-programmazione-web"],"views":141,"_links":{"self":[{"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/posts\/211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=211"}],"version-history":[{"count":3,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/posts\/211\/revisions"}],"predecessor-version":[{"id":250,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=\/wp\/v2\/posts\/211\/revisions\/250"}],"wp:attachment":[{"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ilbytecidio.it\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}