2013-07-09 202 views
5

我有一個數據庫,它存儲了帶有Unicode字符的視頻遊戲名稱,但我無法弄清楚在將它們打印到HTML響應時如何正確地轉義這些Unicode字符。打印Unicode字符PHP

舉例來說,當我打印與像祕境名稱的所有比賽,我得到這個:

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

但它應該顯示此:

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

我跑了快速的JavaScript逃逸功能看看哪個Unicode字符是,並發現它是\u2122

如果我能讓字符正確顯示,那麼我沒有完全逃避字符串中每個字符的問題。我的猜測是,以某種方式找到字符串中的每個字符的十六進制表示,並有PHP呈現Unicode字符是這樣的:

print "&#x2122"; 

請指導我對Unicode轉義爲HTML友好的字符串的最佳方法。我之前爲JavaScript做過類似的工作,但JavaScript具有內置的escape和unescape功能。

但我不知道任何具有類似功能的PHP函數。我已閱讀ord函數,但它僅返回給定字符的ASCII字符代碼,因此不正確地顯示™™。我希望這個函數能夠適用於任何包含有效Unicode字符的字符串。

回答

14

它看起來就像你有UTF-8編碼字符串在內部,PHP將它們輸出正常,但您的瀏覽器不能自動檢測編碼(它決定ISO 8859-1或其他編碼)。

,最好的辦法是告訴UTF-8正在通過發送相應的HTTP頭中使用瀏覽器:

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

然後,您可以留下您的代碼的其餘部分,是和唐不必HTML編碼實體或創建其他混亂。

如果你願意,你可以另外使用<meta>標籤聲明中生成的HTML編碼:

  • <meta http-equiv=Content-Type content="text/html; charset=UTF-8">爲HTML < = 4.01
  • <meta charset="UTF-8">爲HTML5

HTTP標頭優先於<meta>標籤,但如果HTML保存爲HD然後再讀取loc,則後者可能很有用盟友。

9

我花了很多時間試圖找到更好的方式來打印unicode代碼的等效字符,我發現的方法不起作用或者它非常複雜。

此說,JSON是能夠代表使用語法Unicode字符 「\ U [unicode_code]」,則:

echo json_decode('"\u00e1"'); 

將打印對應的Unicode字符,在這種情況下:一。

P.D.請注意簡單和雙引號。如果你不把這兩個都行不通。

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)).'"'); 
}