浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

【PHP】var_dumpだけでデバッグする時に使える手法色々

 やんごとなき理由により PHP のソースコード内に var_dump を埋め込み、var_dump結果をwebページ上で表示する方法のみでデバッグをする必要がある時があります。この様な時に使える var_dump をいい感じに使う方法を5つか紹介します。

 1つ目は見た目を整える方法です。こういった改行の維持をせずに var_dump するとオブジェクトや配列の表示結果や連続した var_dump が見難くなります。

echo '<pre>';
var_dump($見たいモノが入った変数);
echo '</pre>';

 2つ目はどこで問題が起きているか調べる方法です。var_dump の対象に __FILE__ と __LINE__ というマジック定数を使う方法です。これらにはそれぞれ「ファイルのフルパスとファイル名 (シンボリックリンクを解決した後のもの)。 インクルードされるファイルの中で使用された場合、インクルードされるファイルの名前が返されます。 」と「ファイル上の現在の行番号。」という値が入っています。

PHP: マジック定数 – Manual

 次の様にすることで問題が起きている場所が分かります。

var_dump(__FILE__ . ':' . __LINE__);
if($someCondition){
    var_dump(__FILE__ . ':' . __LINE__);
}else {
    /** どちらの分岐に行ったかわかります **/
    var_dump(__FILE__ . ':' . __LINE__);
}
var_dump(__FILE__ . ':' . __LINE__);
// 処理A
/**
 * ある var_dump 結果までが画面に表示され、ある var_dump 結果から先が画面に表示されない場合、
 * それらの var_dump 同士の間の処理に何か問題があるとわかります。
 * 例えば ↑ の var_dump で表示されて ↓ の var_dump で表示されない場合、
 * 処理Aに問題があるとわかります。
 */
var_dump(__FILE__ . ':' . __LINE__);

 もし複数のファイルに跨って調査する必要がないのであれば単にvar_dump(__LINE__);とするだけで十分です。

 3つ目は問題が何が原因で起きているか調べる方法です。debug_print_backtrace 関数を用いる、あるいは debug_backtrace 関数の結果を var_dump することによって、問題の場所までのバックトレースを表示できます。

PHP: debug_print_backtrace – Manual
PHP: debug_backtrace – Manual

 単に流れを見るだけならば debug_print_backtrace が手軽ですが、debug_backtrace を介することで表示内容を制御することもできます。これは知りたいことやネストの深さに応じて使い分けると便利です。

<?php

appFunctionA();

function appFunctionA()
{
    functionB();
}

function functionB()
{
    appFunctionB();
}

function appFunctionB()
{
    functionC();
}

function functionC()
{
    // debug_print_backtraceなら流れだけがパパっと表示されます。
    debug_print_backtrace();
    /*
#0 C:\絶対パス\tmp.php(17): functionC()
#1 C:\絶対パス\tmp.php(12): appFunctionB()
#2 C:\絶対パス\tmp.php(7): functionB()
#3 C:\絶対パス\tmp.php(3): appFunctionA()
     */

    // debug_backtraceなら特定の文字列を含む関数の流れのみを表示など、制御ができます。
    $trace = array_filter(debug_backtrace(), function ($v) {
        return str_contains($v['function'], 'app');
    });
    var_dump($trace);
    /*
array(2) {
  [1]=>
  array(4) {
    ["file"]=>
    string(64) "C:\PhpStormProjects\_CPOINTLAB\SEIBUGOZAI\SEIBUGOZAI_WEB\tmp.php"
    ["line"]=>
    int(12)
    ["function"]=>
    string(12) "appFunctionB"
    ["args"]=>
    array(0) {
    }
  }
  [3]=>
  array(4) {
    ["file"]=>
    string(64) "C:\PhpStormProjects\_CPOINTLAB\SEIBUGOZAI\SEIBUGOZAI_WEB\tmp.php"
    ["line"]=>
    int(3)
    ["function"]=>
    string(12) "appFunctionA"
    ["args"]=>
    array(0) {
    }
  }
}
     */
}


?>

 4つ目は今何がどうなっているかを把握する方法です。PHPには呼ばれたスコープ内の変数全てのリストを返す get_defined_vars という関数があります。これを用いることで今何がどうなっているのかの瞬間を見ることができ、ちょっとしたデバッガーを使っている気分になれます。
PHP: get_defined_vars – Manual

var_dump(get_defined_vars());

 5つ目は var_dump した文字列がブラウザ上に表示されない時に対処する方法です。その様な時は大体、出力した文字列がHTMLとして解釈されている時です。このため次の様にエスケープしてやることで対処できます。

$html = '<div>aaa</div>';
var_dump(htmlspecialchars($html,ENT_QUOTES));
// string(26) "<div>aaa</div>" 

 エスケープすることによって文字列長と表示されている文字列の長さが合わなくなってしまいますが var_dump 結果が隠れなくなります。

 これらの方法を活用することで、var_dumpだけでのデバッグでも比較的効率的に問題や状況の把握が行えるようになります。

  • この記事いいね! (0)