我实际上是想知道 PHP ^7 是否最终有一个本机mb_sprintf()
但显然没有 xD。
为了完整起见,这是我在一些旧项目中一直使用的简单解决方案。strlen
它只是将&之间的差异添加mb_strlen
到所需的$targetLengh
. 为了便于比较,仅添加了非多字节示例 =)。
$text = "Gultigkeitsprufung ist fehlgeschlagen: %{errors}";
$mbText = "Gültigkeitsprüfung ist fehlgeschlagen: %{errors}";
$mbTextRussian = "Проверка не удалась: %{errors}";
$targetLength = 60;
$mbTargetLength = strlen($mbText) - mb_strlen($mbText) + $targetLength;
$mbRussianTargetLength = strlen($mbTextRussian) - mb_strlen($mbTextRussian) + $targetLength;
printf("%{$targetLength}s\n", $text);
printf("%{$mbTargetLength}s\n", $mbText);
printf("%{$mbRussianTargetLength}s\n", $mbTextRussian);
结果
Gultigkeitsprufung ist fehlgeschlagen: %{errors}
Gültigkeitsprüfung ist fehlgeschlagen: %{errors}
Проверка не удалась: %{errors}
更新 2019-06-12
@flowtron 让我再想一想。一个简单的mb_sprintf()
可能看起来像这样。
function mb_sprintf($format, ...$args) {
$params = $args;
$callback = function ($length) use (&$params) {
$value = array_shift($params);
return strlen($value) - mb_strlen($value) + $length[0];
};
$format = preg_replace_callback('/(?<=%|%-)\d+(?=s)/', $callback, $format);
return sprintf($format, ...$args);
}
echo mb_sprintf("%-10s %-10s %10s\n", 'thüs', 'wörks', 'ök');
echo mb_sprintf("%-10s %-10s %10s\n", 'this', 'works', 'ok');
结果
thüs wörks ök
this works ok
我在这里只做了一些快乐的路径测试,但它适用于 PHP >=5.6,应该足以让人们了解如何封装行为。但它不适用于重复/顺序修饰符 - 例如%1$20s
将被忽略/保持不变。