print_r関数とvar_dump関数
デバッグ時にはprint_r関数とvar_dump関数を比較的よく利用していますが、そろそろ限界が近づいてきました。
コンソール上でCLI版PHPを使って確認する分には全然問題ないのですが、Web実行環境でこれらの関数を使う時に、わざわざ「<PRE>」タグとか入れるのが面倒になってきた。。。要は見た目の問題なのですが。
という訳で、こんなモノを用意。
--- php-4.4.8,orig/ext/standard/var.c 2007-12-31 16:22:53.000000000 +0900 +++ php-4.4.8/ext/standard/var.c 2008-01-18 21:27:06.000000000 +0900 @@ -33,6 +33,7 @@ #include "php_smart_str.h" #include "basic_functions.h" #include "php_incomplete_class.h" +#include "SAPI.h" #define COMMON ((*struc)->is_ref ? "&" : "") #define Z_REFCOUNT_PP(a) ((*a)->refcount) @@ -138,6 +139,7 @@ zval ***args; int argc; int i; + int flg = 0; argc = ZEND_NUM_ARGS(); @@ -147,9 +149,21 @@ WRONG_PARAM_COUNT; } + if (sapi_module.name && strcasecmp("cli", sapi_module.name) != 0 ) { + flg = 1; + } + + if (flg) { + php_printf("<PRE>\n"); + } + for (i=0; i<argc; i++) php_var_dump(args[i], 1 TSRMLS_CC); + if (flg) { + php_printf("</PRE>\n"); + } + efree(args); } /* }}} */ --- php-4.4.8,orig/ext/standard/basic_functions.c 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/standard/basic_functions.c 2008-01-18 21:27:06.000000000 +0900 @@ -2576,6 +2576,7 @@ { zval *var; zend_bool i = 0; + int flg = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) { RETURN_FALSE; @@ -2585,8 +2586,20 @@ php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } + if (!i && sapi_module.name && strcasecmp("cli", sapi_module.name) != 0 ) { + flg = 1; + } + + if (!i && flg) { + php_printf("<PRE>\n"); + } + zend_print_pval_r(var, 0); + if (!i && flg) { + php_printf("</PRE>\n"); + } + if (i) { php_ob_get_buffer (return_value TSRMLS_CC); php_end_ob_buffer (0, 0 TSRMLS_CC); --- php-5.2.5,orig/ext/standard/var.c 2007-10-04 22:31:11.000000000 +0900 +++ php-5.2.5/ext/standard/var.c 2008-01-18 21:32:15.000000000 +0900 @@ -34,6 +34,7 @@ #include "php_smart_str.h" #include "basic_functions.h" #include "php_incomplete_class.h" +#include "SAPI.h" #define COMMON ((*struc)->is_ref ? "&" : "") #define Z_REFCOUNT_PP(a) ((*a)->refcount) @@ -173,6 +174,7 @@ zval ***args; int argc; int i; + int flg = 0; argc = ZEND_NUM_ARGS(); @@ -182,9 +184,21 @@ WRONG_PARAM_COUNT; } + if (sapi_module.name && strcasecmp("cli", sapi_module.name) != 0 ) { + flg = 1; + } + + if (flg) { + php_printf("<PRE>\n"); + } + for (i=0; i<argc; i++) php_var_dump(args[i], 1 TSRMLS_CC); + if (flg) { + php_printf("</PRE>\n"); + } + efree(args); } /* }}} */ --- php-5.2.5,orig/ext/standard/basic_functions.c 2007-10-22 16:37:20.000000000 +0900 +++ php-5.2.5/ext/standard/basic_functions.c 2008-01-18 21:32:15.000000000 +0900 @@ -5810,6 +5810,7 @@ { zval *var; zend_bool i = 0; + int flg = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) { RETURN_FALSE; @@ -5819,8 +5820,20 @@ php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } + if (!i && sapi_module.name && strcasecmp("cli", sapi_module.name) != 0 ) { + flg = 1; + } + + if (!i && flg) { + php_printf("<PRE>\n"); + } + zend_print_zval_r(var, 0 TSRMLS_CC); + if (!i && flg) { + php_printf("</PRE>\n"); + } + if (i) { php_ob_get_buffer (return_value TSRMLS_CC); php_end_ob_buffer (0, 0 TSRMLS_CC);
これらを適用すると、CLI版PHP以外のPHPで実行した場合、自動的に「<PRE>」タグを付与します。
print_r関数の第2引数を指定した場合は付与しません。
% cat ./var.php <?php $a = array( 1, 2, 3 ); var_dump( $a ); $b = print_r( $a, true ); echo $b; print_r( $a ); ?> % php-4.4.8/sapi/cli/php ./var.php array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } Array ( [0] => 1 [1] => 2 [2] => 3 ) Array ( [0] => 1 [1] => 2 [2] => 3 ) % php-5.2.5/sapi/cli/php ./var.php array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } Array ( [0] => 1 [1] => 2 [2] => 3 ) Array ( [0] => 1 [1] => 2 [2] => 3 ) % php-4.4.8/sapi/cgi/php -q ./var.php <PRE> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } </PRE> Array ( [0] => 1 [1] => 2 [2] => 3 ) <PRE> Array ( [0] => 1 [1] => 2 [2] => 3 ) </PRE> % php-5.2.5/sapi/cgi/php-cgi -q ./var.php <PRE> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } </PRE> Array ( [0] => 1 [1] => 2 [2] => 3 ) <PRE> Array ( [0] => 1 [1] => 2 [2] => 3 ) </PRE>
精神的に(ちょっとだけ)開放された。個人的には地味に便利。もっと良い方法があれば教えてください(ぉ
きっと、巷の有名なフレームワークなんかは便利なデバッグ用の関数が用意されているんだろうなー。
オールド・タイプでスミマセン。某代表取締役に顔向けできませんね。
それにしても、2008年度の最初の改善がコレっていうのも今年一年を物語っているような気がする。(w
個人的に思うのは、この手のデバッグ(や環境情報取得が)目的の関数は何かしらの制限をかけたい気分。
php.iniディレクティブのdisable_functionsエントリを使って制御すればいいんだけど、個人的には定数を有効にして開発環境じゃなければ処理しない、みたいな制御を追加したい。両方併用する事で(より)安心感を得られます。