PHP Tips | 文字列処理:ログ・表示向け - デバッグ用 var_export 文字列化

PHP PHP
スポンサーリンク

「デバッグ用 var_export 文字列化」とは何をしたいのか

デバッグしているとき、「この変数の中身、今どうなってるの?」って何度も思いますよね。
配列、オブジェクト、ネストしたデータ構造……目で確認できる形にしてログに出したり、一時的に画面に出したりしたくなります。

PHP には var_dump()print_r() がありますが、
ログに出す・文字列として扱う、という用途には var_export() がとても相性がいいです。

「デバッグ用 var_export 文字列化」というのは、
「どんな値でも、とりあえず“読める文字列”にしてくれる安全な変換関数」を 1 本用意しておこう、という話です。


var_export の基本を押さえる

var_export は「PHPコードとして読める形」にしてくれる

var_export() は、値を「PHPコードとして再現できる形の文字列」にしてくれます。

$data = ['id' => 123, 'name' => 'Taro'];

var_export($data);
PHP

出力はこんな感じです。

array (
  'id' => 123,
  'name' => 'Taro',
)
PHP

ポイントは、var_export() には第 2 引数があることです。

var_export(mixed $value, bool $return = false): string|true
PHP

$return = true にすると、「画面に出力する」のではなく「文字列として返す」モードになります。

$str = var_export($data, true);

echo $str;
// array (
//   'id' => 123,
//   'name' => 'Taro',
// )
PHP

この「文字列として返す」モードが、ログやデバッグ用ユーティリティの土台になります。


コアとなる「デバッグ用文字列化」関数を作る

まずは素直に var_export をラップする

一番シンプルな形は、こうです。

/**
 * デバッグ用に、任意の値を var_export で文字列化する
 */
function debug_export(mixed $value): string
{
    return var_export($value, true);
}
PHP

使い方はとても簡単です。

$user = [
    'id'   => 123,
    'name' => '山田太郎',
    'tags' => ['admin', 'beta'],
];

error_log('user=' . debug_export($user));
PHP

ログには、例えばこんな感じで出ます。

user=array (
  'id' => 123,
  'name' => '山田太郎',
  'tags' => 
  array (
    0 => 'admin',
    1 => 'beta',
  ),
)
PHP

配列の構造がそのまま見えるので、「何が入っているか」を一目で確認できます。


実務で困るポイント①:長すぎる出力をどうするか

ネストが深い・要素が多いと、とんでもなく長くなる

大きな配列やオブジェクトを var_export() すると、
ログ 1 行が何千行分にも相当する長さになることがあります。

ログビューアが重くなる。
他のログが埋もれる。
grep しても見づらい。

そこで、「デバッグ用 var_export 文字列化」に「長さ制限」を足しておくと便利です。

/**
 * デバッグ用 var_export 文字列化(長さ制限付き)
 */
function debug_export_short(mixed $value, int $maxLength = 2000): string
{
    $str = var_export($value, true);

    // 制御文字を軽く落としておく(お好み)
    $str = preg_replace('/[\x00-\x1F\x7F]/', '', $str) ?? '';

    if (mb_strlen($str, 'UTF-8') > $maxLength) {
        $str = mb_substr($str, 0, $maxLength, 'UTF-8') . '... (truncated)';
    }

    return $str;
}
PHP

使い方の例です。

error_log('payload=' . debug_export_short($payload, 1000));
PHP

これで、「構造は分かるけど、ログが暴走しない」バランスを取れます。


実務で困るポイント②:ログを 1 行で見たい場合

改行だらけだと一覧性が落ちる

var_export() の出力は、きれいに整形されている代わりに「複数行」です。
ログを一覧で眺めたいときには、1 行にまとまっていたほうが見やすいことも多いです。

その場合は、「改行やタブをスペースに変える」前処理を足します。

/**
 * デバッグ用 var_export 文字列化(1 行ログ向け)
 */
function debug_export_one_line(mixed $value, int $maxLength = 2000): string
{
    $str = var_export($value, true);

    // 改行・タブをスペースに
    $str = str_replace(["\r", "\n", "\t"], ' ', $str);

    // 連続スペースを 1 個に圧縮(お好み)
    $str = preg_replace('/\s+/', ' ', $str) ?? '';

    if (mb_strlen($str, 'UTF-8') > $maxLength) {
        $str = mb_substr($str, 0, $maxLength, 'UTF-8') . '... (truncated)';
    }

    return $str;
}
PHP

使い方の例です。

error_log('context=' . debug_export_one_line($context, 500));
PHP

ログには、例えばこう出ます。

context=array ( 'id' => 123, 'name' => '山田太郎', 'tags' => array ( 0 => 'admin', 1 => 'beta', ), )
PHP

1 行で収まるので、他のログと並べて見やすくなります。


var_dump / print_r ではなく var_export を選ぶ理由

var_dump は「人間には見やすいが、文字列化しづらい」

var_dump() は、型情報も含めて詳細に出してくれるので、
「画面に直接出して確認する」にはとても便利です。

ただし、var_dump() は「返り値がない(直接出力する)」ので、
ログに出すために「文字列として扱う」には向きません。

ob_start()ob_get_clean() でバッファリングすれば文字列化できますが、
毎回それをやるのは少し重いし、コードもごちゃつきます。

var_export は「そのまま文字列として扱える」

一方、var_export($value, true) は最初から「文字列を返す」モードがあるので、
ログ・ファイル・メールなど、どこにでも流し込みやすいです。

さらに、「PHPコードとして再現できる形」なので、
必要ならそのままコピペしてテストコードに貼る、という使い方もできます。

この「文字列として扱いやすい」「再利用しやすい」という点が、
デバッグ用ユーティリティとして var_export を選ぶ大きな理由です。


まとめ:今日からの「デバッグ用 var_export 文字列化」ユーティリティ

やりたいことはシンプルで、「どんな値でも、とりあえず読める文字列にしてログや画面に出せるようにする」ことです。

そのために、

var_export($value, true) で文字列化する。
必要に応じて、長さ制限をかける。
ログ向けには、改行やタブをスペースにして 1 行にする。

という処理を 1 本の関数に閉じ込めておきます。

基本形はこれです。

function debug_export(mixed $value): string
{
    return var_export($value, true);
}
PHP

ログ向けに少し強化した版は、例えばこうです。

function debug_export_one_line(mixed $value, int $maxLength = 2000): string
{
    $str = var_export($value, true);
    $str = str_replace(["\r", "\n", "\t"], ' ', $str);
    $str = preg_replace('/\s+/', ' ', $str) ?? '';

    if (mb_strlen($str, 'UTF-8') > $maxLength) {
        $str = mb_substr($str, 0, $maxLength, 'UTF-8') . '... (truncated)';
    }

    return $str;
}
PHP

もし、あなたのコードのどこかで「error_log(print_r($var, true));」のような行があれば、
そこをこのユーティリティに差し替えてみてください。
ログの見やすさと、デバッグ時の再利用性が、じわっと上がるはずです。

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