【PHP実践|実務向け】PHPでテキストメールやログを美しく整える!マルチバイト対応の「テキスト表」作成術

1. 導入:なぜテキストでの表出力が必要なのか

実務において、Webブラウザ上の表示だけでなく、テキストメールの配信やCLI(コマンドライン)用のログ出力を行う際、データを綺麗に整列させたいという場面は多々あります。特に、全角文字と半角文字が混在する日本語環境では、単純なスペース埋めだけでは桁が揃わず、ガタガタになってしまいがちです。この記事では、PHPを使ってマルチバイト文字を考慮した「テキスト表」を生成する実用的なロジックを解説します。

2. 基礎知識:マルチバイト文字の幅と表示の仕組み

テキストを綺麗に揃えるための鍵は、「文字数」と「表示幅(カラム幅)」の区別にあります。
PHPの標準関数である strlen() や mb_strlen() は文字数を返しますが、これらは「文字の見た目の幅」を考慮しません。例えば、半角の「A」は幅1ですが、全角の「あ」は幅2として扱う必要があります。
今回の実装では、mb_strwidth() 関数を使用します。これにより、日本語環境でも正確に表示上の幅を計算し、適切にスペースをパディングすることが可能になります。

3. 実装のポイント

表を整形する際の最大の課題は「指定した文字数を超えた場合の折り返し」です。
1. 文字列の分割(breakString): 指定したカラム幅を超えたら改行コードを挿入する処理を行います。
2. 行の正規化: 文字列1と文字列2の行数が異なる場合(例えば項目名が長くて2行になり、価格が1行の場合)、少ない方に空行を補完してペアを揃えます。
3. パディング: mb_strwidth() を使い、残りの余白を正確にスペースで埋めます。

4. サンプルプログラム

このコードは、そのままコピーしてPHP環境で動作確認が可能です。

  • テキスト表を生成するメイン関数
  • /
    function textTable($text1, $text2, $length1, $length2, $spacing = ‘ ‘) {
    $text1 = breakString($text1, $length1);
    $text2 = breakString($text2, $length2);

    $lines1 = preg_split(‘/\R/’, $text1);
    $lines2 = preg_split(‘/\R/’, $text2);

    $maxLines = max(count($lines1), count($lines2));
    $result = ”;

    for ($i = 0; $i < $maxLines; $i++) { $line1 = $lines1[$i] ?? ''; $line2 = $lines2[$i] ?? ''; // mb_strwidthで表示上の幅を計算し、必要な分だけスペースを埋める $pad1 = str_repeat(' ', $length1 - mb_strwidth($line1)); $pad2 = str_repeat(' ', $length2 - mb_strwidth($line2)); // 右寄せにする場合は、$pad2 . $line2 の順序を入れ替える $result .= $line1 . $pad1 . $spacing . $pad2 . $line2 . PHP_EOL; } return $result; } /

    • 指定幅で文字列を強制改行する関数

    /
    function breakString($text, $length) {
    $chars = mb_str_split($text); // PHP 7.4以上推奨
    $result = ”;
    $currentWidth = 0;

    foreach ($chars as $char) {
    $width = mb_strwidth($char);
    if ($currentWidth + $width > $length) {
    $result .= PHP_EOL . $char;
    $currentWidth = $width;
    } else {
    $result .= $char;
    $currentWidth += $width;
    }
    }
    return $result;
    }

    // 実行例
    $items = [
    [‘たまねぎ’, ‘400円’],
    [‘魚沼産コシヒカリ 4kg’, ‘2,780円’]
    ];

    foreach ($items as $item) {
    // 第3引数(左幅12), 第4引数(右幅8)
    echo textTable($item[0], $item[1], 12, 8);
    }
    ?>

    5. 応用・注意点

    ・フォント選びの重要性
    このロジックは「等幅フォント」を前提としています。Webブラウザで表示する場合は、必ずCSSで monospace を指定してください。そうでない場合、どんなに計算が正確でもズレて見えてしまいます。

    ・タブ文字の罠
    テキストメールなどでタブ文字(\t)が含まれていると、表示幅の計算が大きく狂います。入力データにタブが含まれる場合は、あらかじめ半角スペースに置換しておくのが現場での定石です。

    ・パフォーマンス
    大量のデータを一度に処理する場合、文字列結合の回数が増えるとメモリを消費します。必要に応じて、結果を文字列変数に溜め込まず、直接ストリーム(php://output)に書き出すように最適化してください。

    タイトルとURLをコピーしました