<?php
namespace imcat;

// basDebug
class basDebug{    

    
/* *****************************************************************************
      *** debug通用代码 
    - var,bug前缀
    - by Peace(XieYS) 2012-02-18
    ***************************************************************************** */
    
    // *** 显示变量 
    
static function varShow($vals$flag=''$lev=3){
        
$trace debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $cnt 0;
        foreach(
$trace as $k=>$row) {
            
$file = empty($row['file']) ? __FILE__ $row['file']; 
            
$line = empty($row['line']) ? -$row['line'];
            
$function = empty($row['function']) ? '' '@'.$row['function'];
            
$bf basename($file); if(in_array($bf, [__FILE__,'helper.php'])){ continue; }
            
$cnt++; if($cnt>$lev){ break; }
            echo 
"$cnt >>> ".self::hidInfo($file)." ($line$function),<br> \n";
        }
        echo 
"\r\n<pre style='line-height:150%;'>"
        if(
$flag) echo "[$flag]\n";
        if(!
is_array($vals)){ $vals=[$vals]; }
        foreach(
$vals as $val){ // print_r($var);
            
echo "<hr>";
            
$exp 1$tp "[".gettype($val)."] "//gettype($val);
            
if(is_string($val)){
                
$tp "[string:".strlen($val)."] ";
            }elseif(
is_array($val)){
                
$tp "[array:".count($val)."] "
            }elseif(
is_object($val)){
                ;
            }else{ 
$exp 0; }
            echo 
$tp;
            if(
$exp){
                echo 
str_replace(array('<','>'), array('&lt;','&gt;'), var_export($val,1));
            }else{
                
var_dump($val);
            }
        }
        echo 
"</pre>\r\n";
    }

    
// 运行统计信息
    
static function runInfo(){
        global 
$_cbase$run $_cbase['run'];
        
$qtime $run['qtime'];
        
$rtime microtime(1) - $run['timer'];
        if(
$rtime>1){
            
$unit 's'
            
$qtime number_format($qtime,4);
            
$rtime number_format($rtime,4);
        }else{
            
$unit 'ms';
            
$qtime number_format($qtime*1000,3);
            
$rtime number_format($rtime*1000,3);
        } 
        
$mem $run['query']."(sql)/".round(memory_get_usage()/1024/1024,3)."(MB)";
        if(
$run['tplname']){
            
$tpl strpos($run['tplname'],':') ? $run['tplname'] : $_cbase['tpl']['vdir'].':'.$run['tplname'];
        }else{
            
$tpl self::runQstr();
        }
        
$info "Run:$qtime/$rtime($unit); $mem$tpl; Upd:".date('Y-m-d H:i:s'); 
        return 
$info;
    }
    static function 
runQstr(){
        
$arr = array('mkv','mod','act','view','parts','kid','did','uid','aid');
        
$res '';
        foreach (
$arr as $key) {
            
$val basReq::val($key);
            
$val && $res .= (empty($res)?'':'&')."$key=$val";
        }
        return 
$res "Qstr:$res'File:'.basename($_SERVER['PHP_SELF']);
    }
    
// 运行Load
    
static function runLoad($pre=0){
        global 
$_cbase;
        
$aclass $_cbase['run']['aclass'];
        
$fix $pre 'pre' '!--';
        
$tmp self::hidInfo($aclass);
        echo 
"\n".($pre '<pre>' '<!--'); 
        
print_r($tmp); 
        echo 
"</".($pre '</pre>' '-->'); 
        
    }

    
// *** 系统参数
    
static function bugPars($pars=''$from=array('GET','SESSION')){
        
$re ''//'GET','POST','COOKIE','SESSION'
        
$arr explode(';',str_replace(array(','), ';'$pars)); 
        foreach(
$arr as $k){
            foreach(
$from as $m){ 
                
$f "_$m"$n $GLOBALS[$f]; 
                
$v = isset($n[$k]) ? $n[$k] : false
                if(
$v!==false$re .= "$k($m)=$v; ";
            } 
        }
        return 
$re;
    }
    
// *** 捕获系统状态信息
    
static function bugInfo($ustr=0){ // url-cut, run-used
        
global $_cbase$info = array(); 
        
$info['ram'] = round(memory_get_usage()/1024/1024,3)."(MB)";
        
$ut microtime(1) - $_cbase['run']['timer']; 
        
$info['used'] = $ustr ? ($ut>number_format($ut,3).'(s)' number_format($ut*1000,3).'(ms)') : $ut;
        
$info['vp'] = $_SERVER['REQUEST_URI'];
        
$info['rp'] = basEnv::serval('ref''(no-ref)');
        foreach(array(
'vp','rp') as $k){
            
$info[$k] = str_replace(array("'","\\"), array("`","#"), $info[$k]);
        }
        
$info['ip'] = basEnv::userIP(1);
        
$info['ua'] = basEnv::userAG();
        
$info['req'] = $_SERVER['REQUEST_METHOD'];
        return 
$info;
    }
    
// *** 错误信息($msg):mod:file-保存到文件; db-数据库; (空)-输出
    
static function bugLogs($act=''$msg=array(), $path='detmp'$mod=''){ 
        global 
$_cbase$rs self::bugInfo($mod=='db'?0:1);
        
$mod || $mod $_cbase['debug']['log_save']; //show,db,file
        
if(is_object($msg)){
            
$msg comParse::jsonEncode($msg); 
        }elseif(
is_array($msg)){
            
$msg comParse::jsonEncode($v);
        }
        if(
$mod!='db'){
            
$darr = [date('Y-m-d H:i:s'), $rs['ip'], $rs['used'], strlen($msg), $rs['ram']];
            
$data "\n".implode(" ,  "$darr)."<br>\n"
            
$data .= "page=$rs[vp]#$rs[req] <- $rs[rp]<br>\n";
            
$data .= "ua=$rs[ua]<br>\n$msg<br>\n";
        }
        if(empty(
$mod) || $mod=='show'){ // show
            
$dcss "border:1px solid #F00; background-color:#FFFFCC; padding:0.5rem; margin:0.5rem; clear:both; display:block;";
            
print_r("\n\n<div style=\"$dcss\">$data</div>\n\n");
        }elseif(
$mod=='db'){
            if(!
in_array($path,['detmp','syact'])){ // 可选?
                
$act .= "|$path"; if(strlen($act)>24$act substr($act,0,24);
                
$path 'detmp';
            }
            
$_cbase['run']['noid'] = empty($_cbase['run']['noid']) ? $_cbase['run']['noid']+1;
            
$kid basKeyid::kidTemp().$_cbase['run']['noid'];
            
$vp strlen($rs['vp'])>240 substr($rs['vp'],0,240) : $rs['vp'];
            
$rp strlen($rs['rp'])>240 substr($rs['rp'],0,240) : $rs['rp'];
            
$maxlen $path=='detmp' 2400 240// text,varchar
            
if(strlen($msg)>$maxlen$msg substr($msg,0,$maxlen).'...'// 64k
            
$vals "'$kid','$act','$rs[used]','$vp#$rs[req]','$rp','".basReq::in($msg)."','$rs[ip]','{$_cbase['run']['stamp']}','$rs[ua]'";
            
db()->run("INSERT INTO ".db()->table("logs_$path",2)."(kid,`act`,used,page,pref,note,aip,atime,aua)VALUES($vals)");     
        }else{ 
// file
            
$data "\n".str_replace("<br>\n""\n"$data);
            if(!
$path){
                
$file "debug/".date('Y-md').".debug"
            }elseif(!
strstr($path,"/")){
                
$file "debug/$path"
            }else{
                
$file $path
            } 
            if(!
strstr($file,'debug/')) $ftmp "debug/$file";
            else 
$ftmp "$file"
            
comFiles::chkDirs(str_replace("//","/",$ftmp), 'vars');
            
$file str_replace("//""/"DIR_VARS."/$ftmp"); 
            
$fh fopen($file"a+");
            
fwrite($fh"\n$data"); fclose($fh);
        }
    }
    
    
// 隐藏:根路径,表前后缀
    
static function hidInfo($str=''$db=0){
        if(!
$db){
            
$a1 = [DIR_IMPSDIR_VARSDIR_IMCATDIR_PROJ];
            
$a2 = ['{ximps}''{xvars}''{imcat}''{proj}'];
            
$str str_replace($a1$a2$str); 
        }else{
            require 
DIR_ROOT.'/cfgs/boot/cfg_db.php';
            
$cdb $_cfgs;
            
$a2 = [" {pre}","{suf} ","`{pre}","{suf}`"];
            foreach(array(
'pre','suf') as $key){
                
$fix $cdb["db_{$key}fix"];
                if(!empty(
$fix)){
                    
$str str_replace(array($fix","$fix ","`$fix","$fix`"), $a2$str);
                }
            }
        }
        return 
$str;
    }
    
// 隐藏:几层跟目录
    
static function hidRoots($path=''$lev=2){
        
$path str_replace("\\"'/'$path);
        if(
substr($path,0,1)=='/'){ $path substr($path,1); }
        
$iniArr explode('/'$path);
        
$pos $lev-1;
        for(
$i=0;$i<$lev;$i++){
            
$pos += strlen($iniArr[$i]);
        }
        
$path '{...}'.substr($path,$pos);
        return 
$path;
    }

    
# log
    
static function log($act=''$sec='get,post,input'){
        
$act || $act $_SERVER['REQUEST_METHOD'];
        
$res['post'] = $_POST;
        
$res['input'] = file_get_contents('php://input');
        
$res['cookie'] = $_COOKIE;
        
$data var_export($res1);
        
$path "debug/$act-".date('Y-md').'.txt'# -His .mt_rand(1000,9999)
        
self::bugLogs($act$data$path'file'); // save
    
}

    
# =========================

    
static function vrVal($key$def=''){ # basEnv::serval
        
return isset($_SERVER[$key]) ? $_SERVER[$key] : $def;
    }

    
// vist-record save # 
    
static function vrSave($act=''$nret=0$timer=0){
        
$rs self::bugInfo(1);
        
$npost = empty($_POST) ? strlen(json_encode($_POST,JSON_UNESCAPED_UNICODE));
        
$data = [date('Y-m-d H:i:s'), $rs['ip'], $rs['used'], $npost$rs['ram'], $rs['rp'], $rs['vp']."#$rs[req]"$rs['ua']];
        
#$isBot = preg_match('/(bot|spider)/i', $rs['ua']);
        #$fp1 = ($isBot ? 'bot_':'com_').date('Y-md-H');
        
$fp1 = ($act $act 'com_').date('Y-md');
        
$fps $_SERVER['DOCUMENT_ROOT']."/@temp/$fp1.txt"# $_SERVER['DOCUMENT_ROOT']
        
file_put_contents($fpsimplode(" ,  "$data)."\n"FILE_APPEND);
    }
    static function 
vrList(){
        
$base $_SERVER['DOCUMENT_ROOT'].'/@temp';
        
$dir = empty($_GET['dir']) ? '' $_GET['dir'];
        
$list glob("$base/".($dir?"$dir/":'')."/*"); 
        
$uri $_SERVER['REQUEST_URI']; if(!strpos($uri,'?')){ $uri .= "?"; }
        echo 
"[$base".($dir?"$dir/":'')."/*]<br>\n";
        foreach(
$list as $fp){
            
$bsname basename($fp);
            if(
is_dir($fp)){
                
$size '[dir]';
                
$dirp "$uri&act=list&dir=$bsname";
                
$wname 'vdir';
            }else{
                
$snum filesize($fp);
                
$size $snum<(1024*1024) ? round($snum/1024,2).'KB' ' ~ ~ ~ ~ ~ ~ '.round($snum/(1024*1024),2).'MB';
                
$dirp "$uri&act=view&fp=$bsname".($dir?"&dir=$dir":'');
                
$wname 'vfp';
            }
            echo 
"<a href='$dirp' target='$wname'>$bsname</a> - $size<br>\n";
        }
    }
    static function 
vrView(){
        
$base $_SERVER['DOCUMENT_ROOT'].'/@temp';
        
$dir = empty($_GET['dir']) ? '' $_GET['dir']; # 2022-06-07
        
$fp = empty($_GET['fp']) ? '' $_GET['fp']; if(strstr($fp,'./')) { die('.x.'); }
        
$fp2 "$base/".($dir?"$dir/":'')."$fp"; if(!file_exists($fp2)){ die('.x.'); }
        
$vtxt = empty($_GET['vtxt']) ? '' $_GET['vtxt'];
        echo 
"<pre>"
        if(
$vtxt){ echo file_get_contents($fp2)."</pre>"; return; }
        
$arr file($fp2); $data = []; $daip = [];
        foreach(
$arr as $row){
            
$rs explode(' ,  '$row);
            
preg_match("/[\d\.\:]+/", (empty($rs[1])?'-':$rs[1]), $itm1); //var_dump($itm1);
            
if(!isset($itm1[0])){
                echo 
"$row\n"; continue;
            }else{ 
# ip
                
$k21 preg_match("/^xf\=/"$rs[1]) ? 'proxy-' 'comm-';
                
preg_match("/(\d+\.\d+\.\d+)\.(\d+)/"$itm1[0], $itm2);
                
$k21 .= empty($itm2[1]) ? $itm1[0] : $itm2[1];
            } 
# ip (xf=::1;ra=192.168.0.1,192.168.0.1;cip=127.0.0.1)
            
$isBot preg_match('/(bot|spider)/i'$rs[7]); # HEAD|
            
$isBad preg_match('/(\.asp|\.jsp|\.ashx|\.asa|\/mytag|\/wp\-includes\/|POST|eval\()/i'$rs[6]);
            
$row str_replace([$rs[6]], ["<a href='{$rs[6]}' target='vpg'>{$rs[6]}</a>"], $row);
            
$data[$k21][] = trim($row) . ($isBad?" --- _ISBAD_" '') . ($isBot?" --- _ISBOT_" '');
            if(!isset(
$daip[$k21])) { $daip[$k21] = $itm1[0]; }
        }
        
ksort($data); $call 0;
        foreach(
$data as $ipre=>$tab1){
            
$cnt count($tab1); $call += $cnt;
            echo 
"<b><a href='https://www.baidu.com/s?wd={$daip[$ipre]}' target='fip'>$ipre</a></b> --- $cnt\n";
            foreach(
$tab1 as $itm3){
                echo 
"    $itm3\n";
            }
        }
        echo(
"\n\n<b> ======= all views : $call</b>\n");
    }

}