我遇到了php彩虹文字功能。 当我运行此函数时,输出文本不支持越南语。
例如:“tôiyêuem”;
<?php
function rainbow($text)
{
/*** initialize the return string ***/
$ret = '';
/*** an array of colors ***/
$colors = array(
'ff00ff', 'ff0099', 'ff0033', 'ff3300',
'ff9900', 'ffff00', '99ff00', '33ff00',
'00ff33', '00ff99', '00ffff', '0099ff',
'0033ff', '3300ff', '9900ff'
);
/*** a counter ***/
$i = 0;
/*** get the length of the text ***/
$textlength = strlen($text);
/*** loop over the text ***/
while($i<=$textlength)
{
/*** loop through the colors ***/
foreach($colors as $value)
{
if ($text[$i] != "")
{
$ret .= '<span style="color:#'.$value.';">'.$text[$i]."</span>";
}
$i++;
}
}
/*** return the highlighted string ***/
$ret = html_entity_decode($ret, ENT_QUOTES, 'UTF-8');
return $ret;
}
echo rainbow('tôi yêu em');
?>
答案 0 :(得分:1)
由于您迭代字符串字节+颜色的方式,您将使用该函数以任何语言获得未初始化的字符串偏移通知。最好通过InfiniteIterator访问颜色,这只会绕着和绕过。
您对越南语的具体问题是其中一些字符由多个字节组成。像strlen()
这样的函数和通过数组括号(如$text[$i]
访问偏移量)不是多字节安全的 - 它们可以处理单个字节而不是字符。
虽然使用mb_strlen()
代替strlen()
来获取字符数而不是字节数可能很诱人,而mb_substr()
而不是$text[$i]
要获得一个字符而不是一个字节,你仍然会分解像è
这样的字素(这里的字符编码为e
后跟combining grave accent。)解决方法是打破将字符串放入带有正则表达式的数组中。
function rainbow($text)
{
$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
$return = '';
$colors = new InfiniteIterator(
new ArrayIterator(
['ff00ff', 'ff0099', 'ff0033', 'ff3300',
'ff9900', 'ffff00', '99ff00', '33ff00',
'00ff33', '00ff99', '00ffff', '0099ff',
'0033ff', '3300ff', '9900ff']
)
);
$colors->rewind();
// Match any codepoint along with any combining marks.
preg_match_all('/.\pM*+/su', $text, $matches);
foreach ($matches[0] as $char)
{
if (preg_match('/^\pZ$/u', $char)) {
// No need to color whitespace or invisible separators.
$return .= $char;
} else {
$return .= "<span style='color:#{$colors->current()};'>$char</span>";
$colors->next();
}
}
return $return;
}
echo rainbow('tôi yêu em evè foo baz');
<span style='color:#ff00ff;'>t</span><span style='color:#ff0099;'>ô</span><span style='color:#ff0033;'>i</span> <span style='color:#ff3300;'>y</span><span style='color:#ff9900;'>ê</span><span style='color:#ffff00;'>u</span> <span style='color:#99ff00;'>e</span><span style='color:#33ff00;'>m</span> <span style='color:#00ff33;'>e</span><span style='color:#00ff99;'>v</span><span style='color:#00ffff;'>è</span> <span style='color:#0099ff;'>f</span><span style='color:#0033ff;'>o</span><span style='color:#3300ff;'>o</span> <span style='color:#9900ff;'>b</span><span style='color:#ff00ff;'>a</span><span style='color:#ff0099;'>z</span>