将 PHP 中的扩展拉丁多字节字符大写并将其输出为转义 HTML

Capitalising Extended-Latin multibyte characters in PHP and outputting them as escaped HTML

我在 PHP 中偶然发现了一个问题,事实证明 比我预期的要难 解决。

在我网站的英文版上,我有一个明文片段:

about-us

我可以直接改成大写的文本形式:

About Us

使用以下内容:

$Text_Array = explode('-', $Plain_Text_Fragment); // ['about', 'us']

for ($i = 0; $i < count($Text_Array); $i++) {
  $Text_Array[$i] = strtoupper($Text_Array[$i][0]) . substr($Text_Array[$i], 1);
}

$Capitalised_Text = implode(' ', $Text_Array); // 'About Us'

事实证明,转换明文片段并不是那么简单:

über-uns

转为大写文字形式:

&Uuml;ber Uns

TLDR: PHP 中最直接的方法是什么?


问题 #1:确定首字母是否为多字节

我只需要将明文片段中每个单词的第一个字母大写,因此,虽然我可以很容易地看出明文片段包含一个或多个多字节字符,但使用:

strlen('über') === mb_strlen('über') // FALSE

仍然没有告诉我明文片段的第一个字母是否是多字节。 (它可能是任何其他字母中的一个或多个)。

我无法隔离和测试$Text_Array[$i][0],因为当然'über'中的'ü'既是$Text_Array[$i][0]又是 $Text_Array[$i][1].

似乎 mb_str_split() 也不存在。


问题 #2:大写 'ü'

一旦我通过了问题 #1(确认 'über' 的第一个字母是多字节的),我不清楚如何将它大写。我想使用 mb_strtoupper() 但我需要在 $Text_Array[$i][0] $Text_Array[$i][1] 上使用它并且没有其他字符(除非有其他多字节字符$Text_Array[$i].

我想我可以解决问题 #2 像这样:

$Text_Array[$i] = mb_strtoupper(substr($Text_Array[$i], 0, 2)) . substr($Text_Array[$i], 2);

我已经检查过了,确实有效。一个下来,两个去。


问题 #3:输出 &Uuml; 而不是 Ü

虽然我使用的是 UTF-8 编码,但我更愿意输出 HTML-escape &Uuml; 而不是原始 Ü。我认为会有一个 PHP 本机函数允许我在两者之间进行转换,并且有:

htmlentities()

但我真的无法判断 htmlentities() 是否正常工作,因为我的 DOM Inspector 和我的 View Source 告诉我他们看到 Ü,而不是 &Uuml;。我很欣赏他们可能会看到后者,他们只是想提供帮助,但我不能绝对确定 PHP 函数 htmlentities() 是否是工作与否。


问题:

PHP 中最直接的转换方法是什么:

über-uns

进入:

&Uuml;ber Uns ?

你已经很接近了,但是一直坚持使用 mb_* 函数:

$Text_Array = explode('-', $Plain_Text_Fragment); // ['about', 'us']

for ($i = 0; $i < count($Text_Array); $i++) {
    $Text_Array[$i] = mb_strtoupper(mb_substr($Text_Array[$i],0,1)) . mb_substr($Text_Array[$i], 1);
}

$Capitalised_Text = implode(' ', $Text_Array); // 'About Us'

问题一:使用mb_substr()

使用mb_substr访问第一个字符。方括号将访问第一个字节,而不是多字节代码点。

问题二:使用mb_strtoupper()

一旦您获得第一个多字节字符,这就不是问题,只需坚持 mb_strtoupper 就可以了。

问题 3:为 htmlentities()

指定字符集

这是通过为 htmlentities 指定字符集来解决的,例如:

htmlentities($Capitalised_Text,null,'UTF-8')

当然如果你的default_charset设置为UTF-8你可以跳过这个直接使用htmlentities()

尝试使用 mb_convert_case

$string = "über-uns";

$string = str_replace("-", " ", $string);

$capitalised = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");

echo htmlentities($capitalised, ENT_HTML5, "UTF-8");