我正在使用Unicode字符做一个简单的 str_pad “─”https://www.compart.com/en/unicode/U+2500
for($i=0;$i<50;$i++){
echo str_pad("", $i,"─");
echo "\n";
}
但PHP CLI中的输出显示:
▒
▒
─
─▒
─▒
──
──▒
──▒
───
───▒
───▒
────
────▒
────▒
─────
─────▒
─────▒
──────
...
所以看起来每个第3行都是正确的,但是第1行和第2行具有不同的行尾字符。
但如果我使用 str_repeat ,这样可以正常工作:
for($i=0;$i<50;$i++){
echo str_repeat("─", $i);
echo "\n";
}
结果:
─
──
───
────
─────
──────
───────
────────
─────────
──────────
...
所以 str_repeat 工作正常,但 str_pad 有一个非常奇怪和意外的结果。知道为什么会这样吗?
答案 0 :(得分:2)
看起来像多字节问题。
使用Unicode字符 str_pad 的快速方法
for($i=0;$i<50;$i++){
echo str_pad("", $i*strlen("─"),"─");
echo "\n";
}
所以这将给出所需的输出:
─
──
───
────
─────
──────
───────
────────
...
但是当你实际上有一个字符串要填充时,这会破坏:
for($i=0;$i<50;$i++){
echo str_pad("X", $i*strlen("─"),"─");
echo "\n";
}
成为:
X
X▒
X─▒
X──▒
X───▒
X────▒
X─────▒
....
所以只需要使用多字节版本的例子: http://php.net/manual/en/function.str-pad.php#116244
for($i=0;$i<50;$i++){
echo mb_str_pad("X", $i,"─");
echo "\n";
}
function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL)
{
$encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;
$padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
$padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
$pad_len -= mb_strlen($str, $encoding);
$targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
$strToRepeatLen = mb_strlen($pad_str, $encoding);
$repeatTimes = ceil($targetLen / $strToRepeatLen);
$repeatedString = str_repeat($pad_str, max(0, $repeatTimes)); // safe if used with valid utf-8 strings
$before = $padBefore ? mb_substr($repeatedString, 0, floor($targetLen), $encoding) : '';
$after = $padAfter ? mb_substr($repeatedString, 0, ceil($targetLen), $encoding) : '';
return $before . $str . $after;
}