CLI(コマンドラインインターフェース)上で、日本語のメッセージやデータを縦に揃えて表示したいことがしばしばあります。特に表のような形式で出力する場合には必須です。この記事ではPHPでこれを実現する方法を紹介します。
使うのは mb_strwidth という関数です。これを使って日本語が表示される時の幅を計算し、適切に空白文字を埋めることで縦を揃えます。これは例えば次のように使えます。
<?php
$data = [
['name' => '浜松太郎', 'score' => 15],
['name' => '次郎', 'score' => 22],
['name' => 'no name', 'score' => 8],
];
// 列ごとに最大幅を計算
$maxWidthList = [];
foreach ($data as $row) {
foreach ($row as $key => $value) {
$width = mb_strwidth($value);
if (!isset($maxWidthList[$key]) || $width > $maxWidthList[$key]) {
$maxWidthList[$key] = $width;
}
}
}
// 最大幅に合わせて左側にスペースを追加する関数を作成
// ↓みたいな適切な回数半角スペースを埋めるstr_pad的な関数が作れます
// [
// 'name' => fn($s) => str_repeat(' ', $maxWidthList['name'] - mb_strwidth($s)) . $s,
// 'score' => fn($s) => str_repeat(' ', $maxWidthList['score'] - mb_strwidth($s)) . $s,
// ]
$padLeft = array_map(fn($w) => fn($s) => str_repeat(' ', $w - mb_strwidth($s)) . $s, $maxWidthList);
// 整列して出力する
foreach ($data as $row) {
$cells = [];
// 最大幅に合わせて左側にスペースを追加して行のセルとして追加
foreach ($row as $key => $value) {
$cells[] = $padLeft[$key]($value);
}
// 行を出力
echo implode(' | ', $cells) . "\n";
}
上記のコードを実行すると次のように整列された出力を得られます。

Symfonyのコンソールコンポーネント等のライブラリを使うまでもないちょっとしたスクリプトを扱う時に便利です。