1.可能有点异想天开,我希望获取调用这个函数的文件的文件名和行数,目前的死办法是外面传__FILE__和__LINE__2.我想获取外面传的调试变量的名称,例如你有个变量叫  $abc = 'fdsafs'; 这样赋值了,然后  debug($abc);   我能在这个函数内部想办法知道这个变量的名称叫  abc3.获取变量类型,类似别的语言的typeof,现在来一个变量,假设它是字符串,却没办法echo typeof($data)   ,却要if(is_string($data))echo 'string';...4.你能提出的更多优化建议,写一写你的改造结果~
====================
这个函数从当初最简单的
function debug($data, $die = false){
    echo '<pre>';
    print_r($data);
    echo '</pre>';
    if($die)die();
}
到今天如下面的代码,已经是一年多了~方便自己调试变量值.我也懒得学那些什么复杂的调试框架什么xDebug..其实我要调试的需求在上面说的和下面代码体现的都有了,没更多的要求.
大家有没有试过,在一个很大的程序体里,到处echo一些值,在调试完后修正代码后,运行时还发现有调试的echo值输出,却不记得这个echo放哪里了- -   所以我需要知道这个调用的文件位置和行号.包括其它更多的调试需求,其实也不是很多,知道变量内容,长度,类型,它变成这个内容的文件位置就行了.上代码:<?php
$a = 'xx';
$b = 45;
$c = true;
$d = false;
$e = null;
$f = new stdClass();
$g = array(
    'a' => 'v1',
    'b' => 'v2',
);
debug($a);
debug($b);
debug($c);
debug($d);
debug($d);
debug($e);
debug($f);
debug($g);
function debug($data, $die = false, $file = null, $line = null){
    static $debugCount = 0; //调试计数器
    echo '<br />================= 新的调试点: <b style="color:red;">'.++$debugCount.'</b>========================<br />';
    if($file)echo "文件名: $file<br />\n";
    if($line)echo "行数: $line<br />\n";
    $len = strlen($data);
    if($len)echo '内容长度:'.$len."<br />\n";
    echo "变量名称: a<br />\n"; //有没有办法获取到外面传参时,debug($a);的变量名称 'a'?
    echo "<pre>\n";
    print_r(var_export($data, true));
    echo "</pre>\n";
    if($die){
        exit('<br /><a href="##" onclick="javascript:history.go(-1)">返回</a>');
    }
    else return $debugCount;
}

解决方案 »

  1.   

    function debug()
    {
        global $config;
        if(!$config['debug']) {
            return;
        }    echo '<pre>';
        foreach(func_get_args() as $var)
        var_dump($var);
        echo '</pre>';
    }
    function fdebug()
    {
        global $config;
        if(!$config['debug']) {
            return;
        }
        foreach(func_get_args() as $var) {
            file_put_contents('./aaa_yii_debug.php', '<?php' . PHP_EOL . var_export($var, true) . PHP_EOL.'?>'.PHP_EOL . PHP_EOL, FILE_APPEND);
        }
    }
    function myfdebug()
    {
        $var = func_get_args();
        if(is_string($var[0])) {
            for($i=1; $i<count($var); $i++) {
                file_put_contents('./aaa_' .$var[0]. '.php', '<?php' . PHP_EOL . var_export($var[$i], true) . PHP_EOL.'?>'.PHP_EOL . PHP_EOL, FILE_APPEND);
            }
        }
        else {
            call_user_func_array('fdebug', $var);
        }
    }
    //个人用的
      

  2.   

    借助异常的跟踪机制:
    function dump(){
    try{
    throw new Exception();
    }catch(Exception $e){
    $trace = $e->getTrace();
    array_shift($trace);
    return $trace;
    }
    }
      

  3.   


    波哥你这个也不能显示调试点的行号~和外部变量名称~我以前对var_dump印象不好..总觉得它输出的东西带着些html代码,现在认真看了看好像可以用了.
    =============直接用没有效果,是不是出了异常才能看到?
    但是我也不是仅仅追踪异常,我要的是显示变量类型,长度,内容,调试点的文件名,行号
      

  4.   


    今晚无意中试用ThinkPHP的throw_exception方法发现可以显示throw的行数,于是追踪了一下函数体,原来它也是new了Exception然后getTrace,呵呵,通过trace回溯信息的file和line字段得到了文件名和长度了.于是我的函数也就大功告成了!已经很满足我的使用需求了~
    分享一下$a = 'xx';
    $b = 45;
    $c = true;
    $d = false;
    $e = null;
    $f = new stdClass();
    $g = array(
        'a' => 'v1',
        'b' => 'v2',
    );
    debug($a);
    debug($b);
    debug($b,11);
    debug($c);
    debug($d);
    debug($d);
    debug($e);
    debug($f);
    debug($g);//第二个参数为11的时候以var_dump方式输出,为1的时候输出完毕时将会停止脚本,默认为0,以var_export形式输出,毕竟总觉得var_dump在打印数组的时候视觉效果太杂乱,认不出哪个元素在哪层或者第几个了.所以想控制输出方式,非万不得已都不想用var_dump
    if(!function_exists('debug')){
        function debug($data, $die = 0){        $exception = new Exception();
            $trace = $exception->getTrace();
            $file = $trace[0]['file'];
            $line = $trace[0]['line'];        //根据文件和行数获得脚本代码
            $phpFilePonter = fopen($file, 'r');
            if($phpFilePonter){
                $fileContents = fread($phpFilePonter, filesize($file));
                $fileLines = explode(PHP_EOL, $fileContents);
                $lineScript = trim($fileLines[$line-1]);
                preg_match('/debug\(.*\)(?= *;)/', $lineScript, $code);
                fclose($phpFilePonter);
                $script = $code[0];
            }else{
                $script = '(无法获取脚本内容)';
            }        echo '<div style="min-width:590px; margin:20px; padding:10px; font-size:14px; border:1px solid #000;">================= 新的调试点: <span style="color:#121E31; font-size:14px;">'.$script.'</span> ========================<br />';
            echo "<font style=\"color:green; font-size:14px;\">$file</font> 第 $line 行<br />\n";
            echo '调试内容:<br />';
            echo '类型:'.gettype($data).'<br />';        echo "值:<br /><br /><pre style=\"font-size:14px;\">\n";
                if($die==11)var_dump($data);
                else print_r(var_export($data, true));
            echo "</pre>\n";        echo '<br /><a href="##" onclick="javascript:history.go(-1)">返回</a></div>';        if($die==1)exit;
        }
    }