我从 db 获取一个 UTF-8 字符串,并尝试回显其第一个字符:
$title = $model->title;
echo $title[0];
我得到:
�
怎么了?
$first_char = mb_substr($title, 0, 1);
您需要使用 PHP 的多字节字符串函数来正确处理 Unicode 字符串:
http://www.php.net/manual/en/ref.mbstring.php
http://www.php.net/manual/en/function.mb-substr.php
您还需要在 HTML 的
<head>
中指定字符编码:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
或:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
您需要考虑以下几件事:
header('Content-Type: utf-8');
]mb_internal_encoding("UTF-8");
mb_substr
代替数组索引符号正如前面在其他问题中提到的,对于 PHP,当尝试获取子字符串时,它不理解多字节字符(例如使用 UTF8 获得的字符)。
其他答案没有提到的是,您应该暗示您想要用于 mb_substr 的编码
例如,我用这个:
mb_substr( "Sunday", 0, 1,'UTF8'); // Returns S
mb_substr( "воскресенье", 0, 1,'UTF8'); // Returns в
PHP 字符串默认不理解多字节字符串,像索引这样的数组会截取第一个字节,如果它恰好不在 ascii 范围内,你会得到这个结果。
使用 mb_substr 方法。
Unicode 很复杂,因为人类语言很复杂。
mb_substr() 适用于许多用例,但它不能处理字素簇(呈现为单个视觉单元的多个 Unicode 字符的组合)。在这种情况下,它会提取第一个字符,但这可能不是您真正想要的。 PHP 的Grapheme Functions 涵盖了这一点;特别是grapheme_substr()。让我们通过几个例子来看看它是如何工作的:
$data = [
'💡',
'🇪🇸 is the flag of Spain',
'Árbol',
"A\xCC\x81rbol",
];
foreach ($data as $string) {
var_dump($string, bin2hex($string));
$output = mb_substr($string, 0, 1);
var_dump($output, bin2hex($output));
$output = grapheme_substr($string, 0, 1);
var_dump($output, bin2hex($output));
echo PHP_EOL;
}
单个字符很简单:
string(4) "💡"
string(8) "f09f92a1"
string(4) "💡"
string(8) "f09f92a1"
string(4) "💡"
string(8) "f09f92a1"
标志是簇组合:
string(29) "🇪🇸 is the flag of Spain"
string(58) "f09f87aaf09f87b82069732074686520666c6167206f6620537061696e"
string(4) "🇪"
string(8) "f09f87aa"
string(8) "🇪🇸"
string(16) "f09f87aaf09f87b8"
带重音的字母通常写为单个字符:
string(6) "Árbol"
string(12) "c38172626f6c"
string(2) "Á"
string(4) "c381"
string(2) "Á"
string(4) "c381"
...但也可以写成字母加重音的组合:
string(7) "Árbol"
string(14) "41cc8172626f6c"
string(1) "A"
string(2) "41"
string(3) "Á"
string(6) "41cc81"