Con il termine "carattere" si intende indicare l'elemento più piccolo che compone un linguaggio scritto dotato di valore semantico, un charset è invece un gruppo di caratteri in codice standard legati alla trasmissione di informazioni, come per esempio l'alfabeto latino.
I gruppi di caratteri codificati sono dei set nei quali ad ogni carattere viene associato un valore scalare detto "point code", i set UNICODE e ASCII sono per esempio dei gruppi codificati che utilizzano un proprio sistema per associare valori differenti e univoci a specifici caratteri; la consonante minuscola "d" corrisponde per esempio al valore scalare "100" in codice ASCII (American Standard Code for Information Interchange o Standard americano per lo scambio di informazioni).
Un carattere codificato, indipendentemente dallo standard di riferimento, necessita di essere decodificato per poter essere utilizzato; in ambito informatico, un carattere codificato deve essere convertito in una corrispondente rappresentazione digitale, ciò vuol dire che il metodo di decodifica impiegato dovrà consentire la traduzione di ogni valore un una corrispondente sequenza di byte
PHP è un linguaggio che mette a disposizione alcuni strumenti per la gestione dei set di caratteri, nel corso di questa breve trattazione verranno descritte le caratteristiche più importanti di questi costrutti.
PHP, UNICODE e UTF-8
L'UNICODE (noto anche come Universal Character Set) è un sistema per la codifica dei caratteri che associa un valore univoco ad ogni carattere utilizzato per la stesura di testi, indipendentemente dalla lingua, dal sistema operativo e dall'applicazione di riferimento; esistono differenti tipologie di codifica per lo standard UNICODE: UTF-8, UTF-16 e UTF-32, dove UTF significa Unicode Transformation Format mentre il numero seguente indica la quantità di bit associata alle sequenze numeriche.
UTF-8, altamente compatibile con i set di caratteri ASCII, è il sistema di codifica multibyte più diffuso per le applicazioni Web based. Si fonda su un'architettura a 8 bit per l'encoding e associa ad ogni valore scalare UNICODE una sequenza di byte in numero oscillante tra 1 e 4. Naturalmente, nel caso in cui si sviluppino applicazioni Web based, uno degli argomenti più rilevanti è quello relativo alla manipolazione delle entità HTML.
PHP mette a disposizione due funzioni native che permettono la traduzione di specifici caratteri nelle corrispondenti entità HTML, queste funzioni sono htmlspecialchars()
e htmlentities()
; inoltre, è disponibile per l'utilizzatore la funzione html_entity_decode()
che permette al contrario la decodifica delle entità HTML nei relativi caratteri. Tutte e tre le funzioni appena citate vengono utilizzate largamente in sede di sviluppo di applicazioni destinate ad Internet, però, forse non tutti sanno che questi costrutti si basano su specifiche mappe di entità (disponibili in un'apposita sezione presente sul manuale ufficiale di PHP) a seconda del set di caratteri di riferimento.
Per spiegare più precisamente quanto appena esposto, è possibile fare riferimento alla funzione get_html_translation_table()
che è stata concepita con lo scopo di restituire in output la tabella di traduzione utilizzata dalle funzioni htmlspecialchars()
e htmlentities()
in fase di conversione delle entità HTML.
Questo sarà possibile grazie all'esistenza di due costanti, HTML_ENTITIES
e HTML_SPECIALCHARS
che permettono di definire quale tabella si desidera interrogare, nel caso in cui non venga specificata alcuna costante come parametro per la funzione, il risultato verrà determinato dalla tabella di default che è HTML_SPECIALCHARS
.
Si osservi l'esempio seguente:
<?php // definizione della costante di traduzione $costante = get_html_translation_table(HTML_ENTITIES); // stringa da codificare $stringa = "Iñtërnâtiônàlizætiøn"; // codifca sulla base della tabella specificata $codifica = strtr($stringa, $costante); // output echo $codifica; ?>
L'esecuzione del codice appena proposto restituirà il seguente output HTML: Iñtërnâtiônàlizætiøn
In generale, nella gestione della codifica UTF-8, sarà comunque abbastanza raro utilizzare entità HTML diverse dalle cinque elencate di seguito:
- "&" (ampersand o "e commerciale") che corrisponde all'entità &.
- " " " ( double quote o "doppi apici") che corrisponde all'entità ".
- " ' " (single quote o "apici singoli") che corrisponde all'entità ' o '§;.
- "<"(inferiore) che corrisponde all'entità <.
- ">" (maggiore) che corrisponde all'entità >.
Queste 5 entità sono infatti quelle che nella maggior parte dei casi possono creare problemi in fase di parsing, gli altri caratteri possono invece essere rappresentati direttamente in UTF-8.
La funzione nativa htmlspecialchars()
mette a disposizione uno strumento semplice e veloce per la generazione di markup HTML e XML, grazie ad essa sarà possibile fornire ad un browser una versione interpretabile di un carattere proponendone la corrispondente versione "convertita" in entità HTML.
La funzione htmlspecialchars()
, a differenza di numerose altre funzioni per il trattamento delle stringhe tramite PHP, considera di default che il testo che le viene passato come parametro sia stato codificato secondo lo standard "ISO-8859-1 (Latin-1) Characters"; questa caratteristica non dovrebbe creare particolari problemi in sede di conversione di una stringa, in ogni caso sarà possibile specificare il set di caratteri di riferimento come terzo argomento da passare alla funzione:
$output = htmlspecialchars($stringa_utf8, ENT_COMPAT, 'UTF-8');
La funzione htmlentities()
permette invece di effettuare la conversione di tutti i caratteri traducibili in entità HTML (oltre ai caratteri di markup precedentemente elencati per htmlspecialchars()
); essa risponde all'esigenza di permettere la visualizzazione del maggior numero di caratteri possibili anche per i browser che supportano soltanto i caratteri con codifica ASCII.
L'esecuzione del breve script proposto di seguito permetterà di visualizzare un elenco completo delle entità HTML generabili tramite le conversioni operate attraverso htmlentities()
, tra di esse vi sono anche le entità corrispondenti alle vocali accentate largamente utilizzate anche nella lingua italiana.
<?php echo '<pre>'; print_r(array_map('htmlspecialchars',get_html_translation_table(HTML_ENTITIES))); echo '</pre> ?>
Naturalmente, la maggior parte dei più importanti programmi per la navigazione su Internet mettono a disposizione un buon supporto per UTF-8, quindi in generale l'utilizzo di htmlspecialchars()
dovrebbe essere più che sufficiente; ma gli output prodotti dalle applicazioni realizzate in PHP, così come i dati da esse gestite, potrebbero essere destinati a scopi diversi rispetto a quello della semplice visualizzazione tramite browser (ad esempio: il salvataggio di informazioni all'interno di un database, l'inclusione di un testo in un editor etc.), quindi l'utilizzo di htmlentities()
potrebbe essere consigliabile a seconda del motivo per cui vengono impiegati i contenuti manipolati.
Sono da segnalare anche le funzioni utf8_encode()
e utf8_decode()
disponibili in PHP per la codifica e la decodifica di caratteri in e da UTF-8; la prima consente l'encoding di stringhe ISO-8859-1 in UTF-8 e accetta come unico parametro la stringa da codificare, la seconda svolge la funzione contraria.
Supporto per il set dei caratteri e PHP 6
In fase di sviluppo ormai da anni, PHP 6 dovrebbe essere presto disponibile con numerose novità; la road map della prossima versione viene revisionata dall'ottobre del lontano 1999 e tra le non poche caratteristiche promesse, oltre all'eliminazione di direttive ormai obsolete e fonti di procedure ormai deprecate (register_globals
, magic_quotes
e supporto per il safe_mode
solo per fare alcuni esempi), PHP 6 dovrebbe mettere a disposizione anche un vero e proprio supporto nativo per l'UNICODE.
Questa piccola rivoluzione è in verità la novità che ha richiesto il lavoro più lungo da parte degli sviluppatori, infatti, perché questo linguaggio potesse fornire il supporto per l'UNICODE è stato praticamente necessario riscrivere lo Zend Engine, il motore di base su cui funziona questo linguaggio.
Dunque, con PHP 6 dovrebbe essere possibile utilizzare funzioni native per la manipolazione delle stringhe come strlen()
, substr()
, strpos()
e molte altre su sequenze di caratteri formattate secondo lo standard UTF-8; presto quindi estensioni come iconv
e mb_string
, utilizzate fino ad ora per supplire all'assenza di un supporto nativo, potranno essere definitivamente abbandonate dagli sviluppatori.
In fase di sviluppo di un'applicazione in PHP o durante la realizzazione di un sito Web basato su questo linguaggio, molto spesso si tende ad ignorare il discorso relativo alla codifica del set di caratteri, nella maggior parte dei casi ci si limita a passare una semplice informazione al browser tramite metatag:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
In questo modo sarà possibile comunicare al programma di navigazione quale tipo di codifica dovrà essere utilizzata per la lettura e il rindirizzamento dei testi contenuti in una pagina.
Con PHP 6, le problematiche relative alla codifica dei caratteri dovrebbero essere invece risolti alla base, il motore Zend Engine sarà infatti in grado di operare autonomamente e automaticamente le operazioni di codifica e di decodifica sia degli input che degli output di un'applicazione in modo che a una base di dati o a un browser per la navigazione Web vengano inviati i dati nel formato richiesto e senza la necessità di utilizzare funzioni aggiuntive destinate alla conversione tra i diversi set di caratteri.
In particolare, la necessità di integrare in PHP 6 un supporto nativo per l'UNICODE è nata dai limiti intrinseci rilevati in due strumenti (o per meglio dire "estensioni") come Iconv e mbstring fino ad ora largamente utilizzate per la gestione dei caratteri codicati.
Iconv è parte di Glibc, la libreria standard per C del progetto GNU, e a partire dalla versione 5 di PHP essa è stata abilitata come modulo predefinito per questo linguaggio in modo da fornire agli sviluppatori dei metodi pronti all'uso per la conversione di stringhe da un set di caratteri locale ad un'altro; Iconv però non è sufficiente per la risoluzione di problematiche legate alla localizzazione, alla ricerca interna alle stringhe, all'identificazioni dei corretti sistemi di encoding e così via.
È possibile fare un discorso leggermente diverso per quanto riguarda mbstring, essa non è una estensione standard per PHP e offre numerosi strumenti in particolare per la gestione dei set di caratteri multibyte (alternativi al formato UNICODE), inoltre, risolve alcuni problemi legati all'encoding ed estende le funzionalità di alcuni costrutti PHP per la manipolazione delle stringhe (overloading delle funzioni). Rimangono in ogni caso in piedi, anche per questa soluzione, i limiti legati ad operazioni di ricerca, localizzazione e così via. Alle considerazioni già fatte si aggiunga il fatto che sia Iconv che mbstring lavorano esclusivamente basandosi su dati di tipo binario, cioè non riconoscono immediatamente i caratteri.
Per la soluzione delle problematiche appena descritte gli sviluppatori di PHP si sono posti degli obbiettivi:
- fornire con la versione 6 un supporto nativo all'UNICODE, cioè slegato da eventuali librerie, estensioni o moduli aggiuntivi;
- definire una separazione chiara tra dati binari, stringhe native e stringhe UNICODE;
- mettere a disposizione strumenti per l'interpretazione letterale delle stringhe UNICODE;
- aggiornare le funzioni già esistenti per la manipolazione delle stringhe in modo da renderle compatibili anche con il nuovo supporto;
- tenere ben presente le esigenze legate alla retro-compatibilità con le applicazioni realizzate utilizzando le precedenti versioni di PHP;
- rendere possibile l'effettuare operazioni anche molto complesse senza per questo dover utilizzare strumenti complicati, mantenendo così la semplicità d'uso che è stata una delle maggiori ragioni di successo di questo linguaggio;
- fornire un supporto per i set di caratteri di qualità equiparabile a linguaggi di programmazione più "evoluti" come per esempio Java.
Concluse le operazioni per la realizzazione del supporto nativo per UNICODE, gli sviluppatori auspicano di ottenere i seguenti risultati:
- utilizzare UTF16 come sistema interno per la codifica;
- utilizzare UNICODE per normalizzare la rappresentazione delle stringhe;
- associare caratteri UNICODE a tutti gli identificatori;
- rendere l'internazionalizzazione esplicita e non implicita;
- permettere di disabilitare il supporto per UNICODE nel caso in cui esso non sia necessario.
Conclusioni
Spesso il discorso relativo all'utilizzo dei set di caratteri non è tenuto nella giusta considerazione, ma se si desidera creare applicazioni o siti Web destinati ad un pubblico più vasto possibile, è bene sapere che PHP mette a disposizione gli strumenti necessari per soddisfare anche questo aspetto.
Nel corso di questa breve trattazione sono state descritte le più importanti funzioni fornite da PHP per le operazioni di codifica e decodifica dei caratteri con particolare attenzione a quelle più comunemente utilizzate in fase di sviluppo. Infine, sono state fornite alcune anticipazioni riguardo a PHP 6, la prossima release del linguaggio che dovrebbe mettere a disposizione un supporto nativo per l'UNICODE.