EC studio EC studio 技術ブログ

2007年07月10日投稿者:山本 正喜

PHPのデバッグに便利な関数 – 基本編

今回は、PHPでデバッグを行う際に
知っておくと便利な関数やちょっとしたTipsをご紹介します。

echo / print

これは基本ですね。
ちなみに、echo や print は関数ではなく構文なので、
カッコが不要です。

  1. echo $something."<br>";
  2. print $something."<br>";

などと省略して書けます。

echoprint は(ほぼ)同じものですが、
echo の方が文字数が少ないので(笑)オススメです。

flush関数を使うと、出力を即座にブラウザに表示させることができます。
長く実行時間のかかる処理で、途中経過を逐次表示させたい場合は、
flushを毎回呼び出すと良いです。
(実際には、flushob_flushを両方呼ぶ必要があります)

(例) flushを使ったサンプル

  1. for ($i = 0;$i <1000;$i++){
  2.     echo $something;
  3.     flush();
  4.     ob_flush();
  5.  
  6.     usleep(300); //効果をわかりやすくするためのスリープ
  7. }

関数にしておくと楽ですね!

  1. /**
  2. * 即座に変数の内容を出力
  3. *
  4. * @param string $var 出力したい文字列
  5. * @return void
  6. */
  7. function fecho($var){
  8.     echo $var;
  9.     flush();
  10.     ob_flush();
  11. }

print_r

これもお世話になっていると思います。
引数の型に関係なく変数の中身を表示できます。
配列や連想配列、オブジェクトなどもOK!

print_rは、PHPのバージョン4.3.0以降、第二引数が追加されました。
(知ってましたか?)

  1. //$somethingのprint_r表示を$outputに入れる
  2. $output = print_r($something,true);

とするとprint_rの出力結果を変数に入れることができます。
(便利です!)

print_rはブラウザで表示させるときは見づらいので、

  1. echo "<pre>";
  2. print_r($something);
  3. echo "</pre>"

などとしてあげるとブラウザで改行がそのまま表示されます。
これも関数にしておくと便利かもしれません。

  1. /**
  2. * preタグで囲んだprint_r出力
  3. *
  4. * @param mixed $var 出力したい変数
  5. * @return void
  6. */
  7. function pre_print_r($var){
  8.     echo "<pre>";
  9.     print_r($var);
  10.     echo "</pre>";
  11. }

スタイルシートなどで見やすくすると良いと思います。

var_dump

print_rの詳細版です。
構造と値だけではなく、型やサイズもあわせて表示します。
オブジェクトの場合、クラス名までわかるので便利です。
厳密にチェックしたい時などに。

例えば

  1. $profile = array(
  2.     "company" => "EC studio",
  3.     "name" => "山本正喜",
  4.     "birth_month" => 12,
  5.     "birth_day" => 16,
  6.     "hobby" => array("dance","programming","travel")
  7. );
  8. var_dump($profile);

とすると

  1. array(5) {
  2.   ["company"]=>
  3.   string(9) "EC studio"
  4.   ["name"]=>
  5.   string(8) "山本正喜"
  6.   ["birth_month"]=>
  7.   int(12)
  8.   ["birth_day"]=>
  9.   int(16)
  10.   ["hobby"]=>
  11.   array(3) {
  12.     [0]=>
  13.     string(5) "dance"
  14.     [1]=>
  15.     string(11) "programming"
  16.     [2]=>
  17.     string(6) "travel"
  18.   }
  19. }

と出力されます。

debug_backtrace

呼び出し元のバックトレースを取得します。
オブジェクト指向や多層的に関数を呼び出すようなプログラムでは、
これがないとデバッグになりません、、、

もともとはPHP5専用に作成された関数だったのですが、あまりの便利さに
PHP4にバックポートされ、PHP4でも使用できるようになりました。(PHP4.3.0以降)

  1. function a($str){
  2.     b($str);
  3. }
  4. function b($str){
  5.     echo $str."\n\n";
  6.     c();
  7. }
  8. function c(){
  9. }
  10.  
  11. a("EC studio");

とすると、出力結果は

  1. EC studio
  2.  
  3. Array
  4. (
  5.     [0] => Array
  6.         (
  7.             [file] => C:\PATH\test.php
  8.             [line] => 20
  9.             [function] => c
  10.             [args] => Array
  11.                 (
  12.                 )
  13.  
  14.         )
  15.  
  16.     [1] => Array
  17.         (
  18.             [file] => C:\PATH\test.php
  19.             [line] => 16
  20.             [function] => b
  21.             [args] => Array
  22.                 (
  23.                     [0] => EC studio
  24.                 )
  25.  
  26.         )
  27.  
  28.     [2] => Array
  29.         (
  30.             [file] => C:\PATH\test.php
  31.             [line] => 26
  32.             [function] => a
  33.             [args] => Array
  34.                 (
  35.                     [0] => EC studio
  36.                 )
  37.  
  38.         )
  39.  
  40. )

となります。

例えば、関数cでエラーが発生した場合、PHPデフォルトのエラーでは
cのエラー行しか表示されません。
debug_backtraceを使えば、そのcの呼び出し元のb,aの引数まで全て追跡できます。

表示がprint_rなので見づらいですが、
自分で見やすい様に表示用の関数を作ると便利です。
(PHP5では、表示用のdebug_print_backtraceという関数も使用できます)

(例) 簡単に作るとこんな感じでしょうか

  1. /**
  2. * バックトレースを表示する
  3. *
  4. * <code>
  5. * //バックトレースを表示
  6. * print_backtrace(debug_backtrace());
  7. * </code>
  8. *
  9. * @param array $backtrace debug_backtraceの返値
  10. * @return void
  11. */
  12. function print_backtrace($backtrace){
  13.    echo "<table border=\"1\" cellpadding=\"3\">";
  14.    echo "<tr align=\"center\"><td>#</td><td>call</td><td>path</td></tr>";
  15.    foreach ($backtrace as $key => $val){
  16.        echo "<tr><td>".$key."</td>";
  17.        echo "<td>".$val['function']."(".print_r($val['args'],true).")</td>";
  18.        echo "<td>".$val['file']." on line ".$val['line']."</td></tr>";
  19.    }
  20.    echo "</table>";
  21. }

glob

これはデバッグだけではなく通常のコーディングにも非常に使える関数です。
(あまり知られてないのが不思議、、)

globを使うと任意のファイルパスを検索できます。
ファイルが正しく存在するのか、正しいフォルダを参照しているのかを
確認する時などに便利です。

  1. //.datのファイルを一覧表示
  2. print_r(glob("./data/*.dat"));

* という指定でワイルドカードを使った検索ができます (便利!)

もちろん、

  1. foreach (glob("./data/*.dat") as $path){
  2.     echo $path."<br>";
  3. }

とforeachで回すこともできるので、opendirなどのディレクトリ関数を使うより、
ずっと簡単かつ直感的にファイルシステムを扱うことができます。

get_included_files

include,requireされた全てのPHPファイル名を返します。
どういう順番でファイルが読み込まれていったのか、
ちゃんとライブラリがロードされているかといったことを確認できます。

なぜか使用したい関数が定義されてなかったり、
二重定義(redeclare)エラーになってしまう時などの調査に便利です。

get_defined_constants

定義されている全ての定数を取得できます。
PHPのデフォルト定数も含まれるので膨大な量になってしまいますが、
使用したい定数が正しく定義されているかを確認する時などに便利です。

PHP5からは、引数を与えると定数をカテゴリ分けしてくれるようになったので、
見やすくなりました。

-----------------------------------------------------------------

以上、今回は主にPHPの組み込み関数の中で
デバッグに便利な関数をご紹介しました。(知らないものはありましたか?)

PHPの特徴でもあるのですが、PHPには膨大な数の組み込み関数が存在します。
PHPの開発をはじめて何年もたってから、
「えっこんな便利な関数あったの?」と気づくことも良くあります。

php.netのマニュアルが非常に良くできているので、
調べるついでに関連する関数などを調べてみると知識の幅が広がると思います。

次回は応用編として、外部ライブラリや自作関数などを使った
デバッグのテクニックを実際のコードを交えて紹介したいと思います!

次回記事:PHPのデバッグに便利な関数 - 応用編へ


関連した記事:
投稿者
人気のエントリー
カテゴリー
最近のエントリー
アーカイブ
Copyright© ChatWork, All Rights Reserved. secured by ESET.