Quando si lavora con più set di caratteri insieme gli accorgimenti da adottare sono parecchi. Bisogna fare attenzione a molte cose :\
Cercherò di riassumere le principali procedure da usare.
Uso dell'estensione mbstring
La prima regola è quella di configurare il php.ini per il supporto dell'estensione mbstring.
Quindi, inizialmente verifica che php_mbstring.dll sia caricato e che le direttive --enable-mbstring e --enable-mbregex siano presenti.
Dopodiché usa queste impostazioni (sempre nel php.ini):
codice:
mbstring.language = Neutral ; indica a php di non preferire alcun linguaggio in particolare
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = On ; Ogni dato in input (per esempio i form) sarà convertito in utf-8
mbstring.http_input = UTF-8 ; Input http solo in utf-8
mbstring.http_output = UTF-8 ; Output http solo in utf-8
mbstring.substitute_character = ? ; Ogni carattere sconosciuto verrà sostituito con un punto interrogativo
mbstring.func_overload = 7 ; abilita l'overload di alcune funzioni per la manipolazione delle stringhe che non sono sicure per i set di caratteri multibyte
Le funzioni che vengono riscritte dall'estensione mbstring sono: strlen(), strpos(), strrpos(), substr(), strtolower(), strtoupper(), substr_count(), ereg(), eregi(), ereg_replace(), eregi_replace() e split().
Se non si desiderasse sostituire tali funzioni native, si può ricorrere a quelle dell'estensione mbstring anteponendo il prefisso "mb_" (mb_strlen(), mb_strpos(), ecc.)
Altri accorgimenti
Uso di trim(), ltrim(), rtrim()
Queste funzioni non sono attivate per i multibyte, quindi non sono consapevoli della possibile presenza di separatori diversi dal classico spazio, tabulazione, ritorno a capo ecc. (tutti elencati qui). Ad esempio non riconosce i caratteri di spazio a larghezza doppia presenti in molti set dell'Asia orientale.
E' possibile rimediare passando alle funzioni un secondo parametro: si tratta di una stringa contenente l'elenco di caratteri da eliminare. Esempio:
Codice PHP:
$str = '???! Testo testo testo !! ?';
echo trim($str, '!?'); // Visualizza " Testo testo testo " (senza le virgolette)
Ad ogni modo, studiare bene l'uso di trim() qualora venga applicata a stringhe multibyte.
Nota: chop() è un alias di rtrim() quindi l'accorgimento appena descritto dovrebbe valere anche per tale funzione.
Uso di split() al posto di explode()
Quando si lavora con set di caratteri multibyte, non usare mai la funzione explode() perché inaffidabile con essi. La funzione split() è meno performante ma sicura con i caratteri multibyte, quindi va usata se si sa in partenza che lo script manipolerà set di caratteri maggiori di un solo byte.
Ordine dei caratteri e funzioni print_f() e simili
Nel caso si lavori con il giapponese, prestare attenzione all'ordine dei specificatori delle funzioni print_f(), sprint_f() e simili, perché cambia l'ordinamento delle parole rispetto alle altre lingue come, per esempio, l'inglese.
In conclusione:
- utilizzare sempre UTF-8 (UTF-32 se si ha a che fare anche con cinese, giapponese e coreano);
- abilitare l'estensione mb_string;
- si può specificare il charset UTF anche nell'(x)html con il tag "meta", come hai scritto te, oppure inviare ogni output degli script in UTF (scelta consigliata);
- salvare ogni file php in UTF
- lavorare con le funzioni di manipolazione delle stringhe verificando il loro supporto ai caratteri multibyte.
Uso della libreria iconv
Esiste anche la libreria "iconv" che offre le opportunità messe a disposizione da mbstring. Inoltre essa possiede la funzione iconv() con la quale permette di convertire una stringa da un set di caratteri a un altro. Può essere molto utile per convertire set di caratteri non previsti prima di elaborarli.
Per l'uso di questa libreria ti rimando alla documentazione e all'articolo linkati di seguito.
Documentazione ufficiale e articoli utili
Infine alcuni link alla documentazione ufficiale e ad articoli utili:
Buon lavoro 
Daniele