前回のデバッグ基本編に続きまして、今回は応用編です。
debuglib
変数表示はprint_rやvar_dumpなどを使用することが多いと思いますが、
<pre>などで囲ったとしてもとても見やすいとは言えません、、。
そこで、debuglib.phpを使用すればとても見やすく表示してくれます。
print_rと同様に、文字列・配列・オブジェクトなどなんでも表示できます。
使い方は簡単で、
-
require("debuglib.php");
-
-
$profile = array(
-
"company" => "EC studio",
-
"name" => "山本正喜",
-
"birth_month" => 12,
-
"birth_day" => 16,
-
"hobby" => array("dance","programming","travel")
-
);
-
-
print_a($profile);
↓この場合表示はこうなります
この様に、debuglib.phpを読み込み、
print_rのかわりにprint_aを使えばOKです。
これは非常に便利なので、使わない手はないです。
ただ、配列やオブジェクトはうまく表示できるのですが、
単体の数値や文字列、null/true/falseは
正しく表示できないのが不便です。
(例)
-
$str = "EC studio";
-
print_a($str);
↓この場合表示はこうなります
また、ライブラリとして読み込む必要があるので、
本番の時にはなるべくシステムを軽くするために、
デバッグの時のみファイルを読み込むようにしたいところです。
そこで、EC studioでは下記の様な関数を
一枚かぶせて使用しています。
-
/**
-
* デバッグプリント
-
*
-
* <pre>
-
* 変数や配列、オブジェクトなどをビジュアルに表示する。
-
* print_rの変わりに使うと便利。
-
*
-
* debuglibの、print_a ラッパー。(debuglib.phpを動的にロードする。)
-
* print_aが出力しないnullや、string、空配列などにも対応している。
-
* </pre>
-
*
-
* @param mixed $val 変数
-
* @param int $mode 0 = 表示 1 = 出力を返す
-
* @param bool $show_object_vars オブジェクトを展開して表示する
-
* @param int $limit 最大表示数 (FALSEで無制限)
-
* @return string $mode = 1の時 出力結果。
-
*/
-
function dprint_r($val,$mode=0,$show_object_vars=FALSE,$limit=FALSE){
-
//debuglib読み込み (print_a関数)
-
require_once("debuglib.php");
-
-
if ($val === null){
-
if ($mode){
-
return "<span style=\"color:red;\">NULL</span>";
-
}else{
-
echo "<span style=\"color:red;\">NULL</span>";
-
}
-
return;
-
}
-
if ($val === false){
-
if ($mode){
-
return "<span style=\"color:red;\">FALSE</span>";
-
}else{
-
echo "<span style=\"color:red;\">FALSE</span>";
-
}
-
return;
-
}
-
if ($val === true){
-
if ($mode){
-
return "<span style=\"color:red;\">TRUE</span>";
-
}else{
-
echo "<span style=\"color:red;\">TRUE</span>";
-
}
-
return;
-
}
-
if ($mode){
-
return "<span style=\"color:#00008B;\">".htmlescape($val)."</span>";
-
}else{
-
echo "<span style=\"color:#00008B;\">".htmlescape($val)."</span>";
-
}
-
return;
-
}
-
if ($mode){
-
return "<span style=\"color:green\">".$val."</span>";
-
}else{
-
echo "<span style=\"color:green\">".$val."</span>";
-
}
-
return;
-
}
-
if ($mode){
-
return "<span style=\"color:green\">array()</span>";
-
}else{
-
echo "<span style=\"color:green\">array()</span>";
-
}
-
return;
-
}
-
-
return print_a($val,$mode,$show_object_vars,$limit);
-
}
print_aのかわりに、このdprint_rを使用しています。
これで使い勝手がぐっとよくなりました。
(print_rの代替として使えるようになりました)
非常に便利なこのdebuglibなのですが、注意が必要な点として、
・配列や要素になっているオブジェクトはデフォルトでは表示されない。
(第3引数にtrueを与えると表示されます)
・循環参照を持つ変数では無限ループが発生する
ということに気をつける必要があります。
循環参照とは、
-
$arr = array();
-
$arr[0] =& $arr;
この様に、配列やオブジェクトなどで要素に自分自身への参照を持つものの事です。
こういった変数を表示させようとすると、debuglibでは無限に変数を展開し続けます。
(環境によってはApacheが停止します)
あまり循環参照を持つ変数を使用することは少ないですが、
お互いを参照し合うオブジェクトなどでも循環参照が発生するので、
注意が必要です。
※PHP組み込みのprint_rやvar_dumpでは循環参照は
**RECURSION**という表示に置き換わりちゃんと表示できます。
dBug
こちらもdebuglibと同様に、変数を表示するライブラリです。
ColdFusionのデバッグ表示機能であるcfdumpタグの機能を
PHPで実現することを目的としたライブラリです。
debuglibと同様に
-
require("dBug.php");
-
-
$profile = array(
-
"company" => "EC studio",
-
"name" => "山本正喜",
-
"birth_month" => 12,
-
"birth_day" => 16,
-
"hobby" => array("dance","programming","travel")
-
);
-
-
new dBug($profile);
この様に使用します。
オブジェクトを new するとデバッグ表示できます。
↓今回の例だと、この様に表示されます
他にもデータベースのリソースや、XMLのデータなども
表示することができます。
こちらのサンプルページを見るdBugでどういった事が
できるかがよくわかると思います。
基本的にはdebuglibと同様の機能ですが、
配列やオブジェクトなどをクリックすると折りたたむ事が
できるなど、より機能的になっています。
また、debuglibではできなかった循環参照の
変数表示もできるようになっています。
(2007/01/15 に実装された様なので、古いバージョンを
使用されている方はアップデートをおすすめします)
ただ、dBug.phpを読み込んだ時点で
javascriptやcssのコードが出力されてしまうので、
システムに組み込むには使いづらいかもしれません。
EC studioではシンプルで見やすいdebuglibの方を採用しています。
あると便利な小さい自作関数
ここではPHPの組み込み関数をちょっとした工夫で使いやすくした関数を
ソースコード付きでご紹介します。
■cprint_r
print_rの表示結果をHTMLタグに埋めこんで表示します。
画面には表示させたくないデバッグ変数の表示や、
本番環境などで緊急にテストしたい時に、、、(汗)
-
/**
-
* コメントで変数を出力する
-
*
-
* 本番などでデバッグ表示したい時などに
-
* ソースをDEBUGで検索すれば見つけやすい
-
*
-
* @param mixed $val 変数
-
*/
-
function cprint_r($val){
-
}
■die_r
dieのprint_r版です。
dieで配列などを表示させたい時に。
(print_rはdebuglibやdBugに置き換えると便利です。)
■count_hook
特定の回数コールされるとtrueを返します。
ループ回数が多いコードのデバッグ時に
仕込んでおくと非常に便利です。
-
/**
-
* 指定回数でtrueする。
-
*
-
* <code>
-
* //30回でbreak
-
* for ($i = 0;$i <100;$i++){
-
* if (count_hook(30)) break;
-
* }
-
* </code>
-
*
-
* ループなどのテストに便利。
-
*
-
* @param int $count 回数
-
* @return bool 回数分コールされた時にtrue
-
*/
-
function count_hook($count){
-
-
$cnt++;
-
-
if ($cnt == $count){
-
$cnt = 0;
-
return true;
-
}
-
-
return false;
-
}
(例)ループの10回目で抜ける
-
for ($i = 0;$i <1000;$i++){
-
//何か重たい処理
-
-
if (count_hook(10)){ //10回目でtrueになる
-
break;
-
}
-
}
breakと組み合わせればループを抜けることもできます。
(dieで変数を表示して終了することも)
■count_die
count_hookのdie版です。
指定回数実行した時にdieを実行します。
(count_hookが必要)
-
/**
-
* 指定回数でdieする。
-
*
-
* <code>
-
* //30回でdie
-
* for ($i = 0;$i <100;$i++){
-
* count_die(30,"30回目");
-
* }
-
* </code>
-
* ループなどのテストに便利。
-
*
-
* @param int $count 回数
-
* @param string $message 表示させたい文字列
-
* @return void
-
*/
-
function count_die($count,$message=""){
-
if (count_hook($count)){
-
}
-
}
(例)ループの10回目でdie
-
for ($i = 0;$i <1000;$i++){
-
//何か重たい処理
-
-
//10回目でdie
-
count_die($something);
-
}
count_hookに比べてシンプルに書けます。
------------------------------------------
以上、デバッグ応用編でした。
PHPは便利な組み込み関数が多いので頼ってしまいがちですが、
同様の機能を持つ外部のライブラリを使用したり、
組み込み関数を組み合わせて少しカスタマイズした関数を
自分用に作ることで、使い勝手がぐっと良くなります。
それでは快適なデバッグライフを!
関連した記事:
■ 「日本でいちばん社員満足度が高い会社の非常識な働き方」


















ページの先頭に戻る
大変参考になりました。ありがとうございます。
debuglibは現在は上記の問題はfixされているみたいです。