2013-02-24 14 views
5

Ho un problema con UTF-8 e mb_strtoupper.PHP: mb_strtoupper non funziona

mb_internal_encoding('UTF-8'); 
$guesstitlestring='Le Courrier de Sáint-Hyácinthe'; 

$encoding=mb_detect_encoding($guesstitlestring); 
if ($encoding!=='UTF-8') $guesstitlestring=mb_convert_encoding($guesstitlestring,'UTF-8',$encoding); 

echo "DEBUG1 $guesstitlestring\n"; 
$guesstitlestring=mb_strtoupper($guesstitlestring); 
echo "DEBUG2 $guesstitlestring\n"; 

Risultato:

DEBUG1 Le Courrier de Sáint-Hyácinthe 
DEBUG2 LE COURRIER DE S?INT-HY?CINTHE 

Non capisco perché questo sta accadendo? Sto cercando di essere il più attento possibile con la codifica. La stringa viene data prima come UTF-8, verificata e possibile riconvertita in UTF-8. È un incubo!

UPDATE

Così ho capito che questo è stato causato da una combinazione di mia entrare gli argomenti tramite la console e gli argomenti a tornare dalla console. Quindi sono stati confusi sia nel modo in cui e la via d'uscita. La soluzione è non inserire nessuno degli argomenti in questo modo, o ottenere gli argomenti in questo modo.

Grazie a tutti per il vostro aiuto nella risoluzione di questo problema!

+0

E 'in corso di eco alla console, ma lo fa, ovviamente, visualizzazione nella console perché i trattini sono lì in DEBUG1. – Alasdair

+1

Qual è la codifica del tuo file .php? Prova a convertirlo in utf-8 senza BOM. – Hast

+0

... mh, prova ad aggiungere setlocale (LC_ALL, 'en_US.UTF-8'); in cima – Federkun

risposta

5

Invece di strtoupper()/mb_strtoupper() utilizzare mb_convert_case() poiché la conversione del maiuscolo è molto complicata tra diverse codifiche, assicurarsi inoltre che la stringa sia UTF-8.

$content = 'Le Courrier de Sáint-Hyácinthe'; 

mb_internal_encoding('UTF-8'); 
if(!mb_check_encoding($content, 'UTF-8') 
    OR !($content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32'))) { 

    $content = mb_convert_encoding($content, 'UTF-8'); 
} 

// LE COURRIER DE SÁINT-HYÁCINTHE 
echo mb_convert_case($content, MB_CASE_UPPER, "UTF-8"); 

esempio di lavoro: http://3v4l.org/enEfm#v443

Vedi anche il mio commento sul sito PHP sul convertitore: http://www.php.net/manual/function.utf8-encode.php#102382

+0

Perché il 'á' è in minuscolo nell'output? – Hast

+0

@Hast non ne sono sicuro. Forse solo al carattere francese che codifica il maiuscolo esiste? – powtac

+0

Ho appena eseguito un esempio dalla domanda nella mia console e ha fatto eco: 'DEBUG2 LE COURRIER DE SÁINT-HYÁCINTHE' – Hast

2

Funziona per me, ma solo quando il file PHP stesso viene salvato come UTF -8 e quando il terminale in cui mi trovo si aspetta UTF-8. Penso che quello che sta succedendo per te è che il file viene salvato come ISO-8859-1 e il tuo terminale si aspetta ISO-8859-1.

In primo luogo, mb_detect_encodingin realtà non funziona per questa stringa. Anche quando il file PHP non è UTF-8, lo segnala comunque come UTF-8.

Quando si stampa la stringa minuscola, stampa caratteri ISO-8859-1 e il terminale li visualizza bene. Quindi, quando si converte in maiuscolo usando UTF-8, questo viene manomesso.

Ho creato due versioni di questo file. L'ho salvato utilizzando il mio editor di testo in ISO-8859-1 come iso-8859-1.php. Poi iconv ho usato per convertire l'intero file in UTF-8 e salvato come utf-8.php

iconv iso-8859-1.php --from iso-8859-1 --to UTF-8 > utf-8.php 

ho aggiunto una linea per stampare il risultato della codifica che mb_detect_encoding rendimenti.

$ file iso-8859-1.php 
iso-8859-1.php: PHP script, ISO-8859 text 

$ php iso-8859-1.php 
ENCODING: UTF-8 
DEBUG1 Le Courrier de S�int-Hy�cinthe 
DEBUG2 LE COURRIER DE S?INT-HY?CINTHE 

$ file utf-8.php 
utf-8.php: PHP script, UTF-8 Unicode text 

$ php utf-8.php 
ENCODING: UTF-8 
DEBUG1 Le Courrier de Sáint-Hyácinthe 
DEBUG2 LE COURRIER DE SÁINT-HYÁCINTHE 

mio terminale in realtà si aspetta testo UTF-8, in modo da quando stampo il testo ISO-8859-1 che venga storpiato. Tutto funziona correttamente quando il file viene salvato come utf-8 e il terminale si aspetta utf-8.

+1

perché mb_detect_encoding non funziona, controllo se la stringa codificata e nuovamente decodificata è ancora la stringa originale nella mia risposta: http://stackoverflow.com/a/15051401/22470 – powtac

+0

OK. Ma non posso farlo perché la stringa è data come argomento nello script PHP sulla console. Quindi ho bisogno di un modo per forzarlo in UTF-8 in qualche modo dallo script PHP già. – Alasdair

+0

Vedere la mia risposta, converto la stringa in UTF-8 indipendentemente dalla stringa di input ... – powtac

2

In realtà, ciò che funziona qui è semplicemente

<?php 
mb_internal_encoding('UTF-8'); 

$x='Le Courrier de Sáint-Hyácinthe'; 
echo mb_strtoupper($x) . "\n"; 

uscite

LE COURRIER DE SÁINT-HYÁCINTHE 

qui funziona direttamente, ma forse nel tuo caso si deve aggiungere utf8_encode:

$x = utf8_encode('Le Courrier de Sáint-Hyácinthe'); 

- -

Un'alternativa che funziona qui senza MB,

<?php 
echo strtoupper(str_replace('á', 'Á', 'Le Courrier de Sáint-Hyácinthe')); 
+0

Funziona solo quando si dispone di una stringa di input UTF-8 appropriata. – powtac

+0

Modificato la risposta. –