4 に答える
内部で UTF-8 でエンコードされた文字列を持っているようで、PHP はそれらを適切に出力しますが、ブラウザはエンコーディングを自動検出できません (ISO 8859-1 または他のエンコーディングを決定します)。
最善の方法は、対応する HTTP ヘッダーを送信して、UTF-8 が使用されていることをブラウザーに伝えることです。
header("content-type: text/html; charset=UTF-8");
次に、コードの残りの部分をそのままにしておくことができ、エンティティを html エンコードしたり、他の混乱を作成したりする必要はありません。
必要に応じて、次のタグを使用して、生成された HTML でエンコーディングを追加で宣言できます。<meta>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
HTML <=4.01 の場合<meta charset="UTF-8">
HTML5 用
HTTP ヘッダーは<meta>
タグよりも優先されますが、HTML が HD に保存されてからローカルで読み取られる場合は、後者が役立つ場合があります。
Unicode コードと同等の char を出力するためのより良い方法を見つけるのに多くの時間を費やしましたが、見つけた方法は機能しないか、非常に複雑でした。
つまり、JSON は構文 "\u[unicode_code]" を使用して Unicode 文字を表すことができます。
echo json_decode('"\u00e1"');
同等の unicode char を出力します。この場合は á です。
PD 単純引用符と二重引用符に注意してください。両方入れないとダメです。
// 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)).'"');
}
これを試して:
echo htmlentities("Uncharted: Drakes Fortune™ \n", ENT_QUOTES, "UTF-8");