2013-07-09 3 views
5

Ho un database che memorizza i nomi di videogiochi con caratteri Unicode ma non riesco a capire come eseguire correttamente l'escape di questi caratteri Unicode quando li stampo su una risposta HTML.Stampa caratteri Unicode PHP

Per esempio, quando stampo tutti i giochi con il nome come Uncharted, ottengo questo:

Uncharted: Drake's Fortuneâ„¢ 
Uncharted 2: Among Thievesâ„¢ 
Uncharted 3: Drake's Deceptionâ„¢ 

ma dovrebbe mostrare questo:

Uncharted: Drake's Fortune™ 
Uncharted 2: Among Thieves™ 
Uncharted 3: Drake's Deception™ 

ho corse una funzione rapida fuga Javascript per vedere quale carattere Unicode è il e ha rilevato che è \u2122.

Non riesco a sfuggire completamente a tutti i caratteri nella stringa se riesco a visualizzare correttamente il carattere . La mia ipotesi è quello di trovare in qualche modo la rappresentazione esadecimale di ogni carattere della stringa e hanno PHP rendere i caratteri Unicode come questo:

print "&#x2122"; 

per favore mi guida attraverso l'approccio migliore per Unicode sfuggire una stringa per essere HTML amichevole. Ho fatto qualcosa di simile per JavaScript qualche tempo fa, ma JavaScript ha una funzione integrata per escape e unescape.

Non sono a conoscenza di alcuna funzione PHP di funzionalità simile. Ho letto della funzione ord, ma restituisce semplicemente il codice carattere ASCII per un dato carattere, da cui la visualizzazione errata dello ™ o dello ™. Mi piacerebbe che questa funzione fosse abbastanza versatile da applicarsi a qualsiasi stringa contenente caratteri Unicode validi.

risposta

14

Sembra che tu hai stringhe UTF-8 codificati internamente, PHP li emette correttamente, ma il browser non riesce a rilevare automaticamente la codifica (che decide per ISO 8859-1 o qualche altra codifica).

Il modo migliore è quello di dire al browser che UTF-8 viene utilizzato inviando la relativa intestazione HTTP:

header("content-type: text/html; charset=UTF-8"); 

Quindi, è possibile lasciare il resto del codice così com'è e don Devo codificare le entità html o creare altro pasticcio.

Se si desidera, è possibile inoltre dichiarare la codifica nel codice HTML generato utilizzando il tag <meta>:

  • <meta http-equiv=Content-Type content="text/html; charset=UTF-8"> per HTML < = 4,01
  • <meta charset="UTF-8"> per HTML5

L'intestazione HTTP ha la priorità sul tag <meta>, ma quest'ultima può essere utile se l'HTML è salvato in HD e quindi legge loc alleato.

9

ho speso un sacco di tempo cercando di trovare il modo migliore per stampare solo il carattere equivalente di un codice unicode, ed i metodi che ho trovato non ha funzionato o semplicemente erano molto complicato.

Detto questo, JSON è in grado di rappresentare i caratteri Unicode utilizzando la sintassi "\ u [unicode_code]", quindi:

echo json_decode('"\u00e1"'); 

stamperà il carattere unicode equivalente, in questo caso: a.

P.D. Nota le citazioni semplici e doppie. Se non li metti entrambi, non funzionerà.

1
// PHP 7.0 
var_dump(
    IntlChar::chr(0x2122), 
    IntlChar::chr(0x1F638) 
); 

var_dump(
    utf8_chr(0x2122), 
    utf8_chr(0x1F638) 
); 

function utf8_chr($cp) { 

    if (!is_int($cp)) { 
     exit("$cp is not integer\n"); 
    } 

    // UTF-8 prohibits characters between U+D800 and U+DFFF 
    // https://tools.ietf.org/html/rfc3629#section-3 
    // 
    // Q: Are there any 16-bit values that are invalid? 
    // http://unicode.org/faq/utf_bom.html#utf16-7 

    if ($cp < 0 || (0xD7FF < $cp && $cp < 0xE000) || 0x10FFFF < $cp) { 
     exit("$cp is out of range\n"); 
    } 

    if ($cp < 0x10000) { 
     return json_decode('"\u'.bin2hex(pack('n', $cp)).'"'); 
    } 

    // Q: Isn’t there a simpler way to do this? 
    // http://unicode.org/faq/utf_bom.html#utf16-4 
    $lead = 0xD800 - (0x10000 >> 10) + ($cp >> 10); 
    $trail = 0xDC00 + ($cp & 0x3FF); 

    return json_decode('"\u'.bin2hex(pack('n', $lead)).'\u'.bin2hex(pack('n', $trail)).'"'); 
}