LoginSignup
3
0

More than 5 years have passed since last update.

PHP で全角1文字を半角2文字としてカウントしたい(等幅フォント向け)

Last updated at Posted at 2018-07-22

TL;DR

CLI アプリの表示など全角文字に合わせて半角の '-' で下線を引きたいが、文字列の長さが合わない。

mb_strwidth を使う

<?php

$string = 'テスト'; //expect 6 chars length such as '------'
$width  = mb_strwidth($string);
$ul     = str_repeat('-', $width);

echo $string, PHP_EOL;
echo $ul, PHP_EOL;


スクリーンショット 2018-07-22 15.35.47.png

注意点

「全角=マルチバイト」というわけではないため、全ての全角文字が2文字としてカウントされるわけではないことに注意してください。

特に記号を扱う場合は注意が必要です。「✅」(bin2hex=e29c85)といった記号や「😀」(bin2hex=f09f9880)といった絵文字などは「mb_strwidth=1」となりますが、(Mac など)OS や使うフォントによって表示は全角になります。

CUI のシェル画面でテキスト表示した際に描画が崩れる(全角文字に隣の半角が埋もれる)のをみたことがあると思いますが、これが原因です。

また、当然ですが、そもそも等幅フォントを使っていない場合はガタガタになります。

<?php

$string = 'テスト';

echo 'mb_strwidth:', PHP_EOL;
echo $string, PHP_EOL;
echo str_repeat('-', mb_strwidth($string)), PHP_EOL, PHP_EOL;

echo 'strlen:', PHP_EOL;
echo $string, PHP_EOL;
echo str_repeat('-', strlen($string)), PHP_EOL, PHP_EOL;

echo 'mb_strlen:', PHP_EOL;
echo $string, PHP_EOL;
echo str_repeat('-', mb_strlen($string)), PHP_EOL, PHP_EOL;


echo '全角記号で1文字になりうる文字', PHP_EOL;

echoWidth('※');
echoWidth('★');
echoWidth('△');
echoWidth('■');
echoWidth('①');
echoWidth('✅');

echo 'PHP version: ', phpversion(), PHP_EOL, PHP_EOL;

function echoWidth($string)
{
    echo $string, ': ', var_dump(mb_strwidth($string, 'utf-8'));
}

出力結果

以下は macOS(10.13.5) + MSゴシックで表示した場合の例

スクリーンショット 2018-07-22 15.32.25.png

参考文献

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0