|
| 1 | +<?php |
| 2 | +/* (C)2005-2021 Found PHP Framework. |
| 3 | +* 官网:http://www.FoundPHP.com |
| 4 | +* 邮箱:master@FoundPHP.com |
| 5 | +* author: 孟大川 |
| 6 | +* version: 1.21.208 |
| 7 | +* start: 2015-05-24 |
| 8 | +* update: 2021-02-08 |
| 9 | +* payment: 授权使用 |
| 10 | +* This is not a freeware, use is subject to license terms. |
| 11 | +* 此软件为授权使用软件,请参考软件协议。 |
| 12 | +* http://www.foundphp.com/?m=agreement |
| 13 | +*/ |
| 14 | +//增加出错日志 |
| 15 | +//注意:如果出现错误代码没有图形界面表示代码串不支持 |
| 16 | + |
| 17 | +class FoundPHP{ |
| 18 | + var $found = '1.116'; |
| 19 | + var $tpl = ''; |
| 20 | + var $files = ''; |
| 21 | + var $set_lang = 'zh'; //语言 |
| 22 | + var $lang = array( |
| 23 | + 'error_code' => '错误代码:', |
| 24 | + 'error_trace' => '错误原因:', |
| 25 | + 'error_from' => '错误溯源:', |
| 26 | + 'error_analysis' => '出错修改建议', |
| 27 | + 'error_details' => '错误详情', |
| 28 | + 'error_type' => '描述', |
| 29 | + 'error_introduce' => '详情', |
| 30 | + 'error_introduce' => '详情', |
| 31 | + 'error_file' => '报错文件', |
| 32 | + 'error_line' => '出错行号', |
| 33 | + 'error_str' => '错误字符:', |
| 34 | + 'error_future' => '(这个问题PHP 7.2 版本以后成为严重错误)', |
| 35 | + 'back' => '后退', |
| 36 | + 'refresh' => '刷新', |
| 37 | + 'fix' => '修复代码', |
| 38 | + 'line' => '行', |
| 39 | + 'think_time' => '您已经思考', |
| 40 | + 'think_hour' => '小时', |
| 41 | + 'think_minute' => '分', |
| 42 | + 'think_second' => '秒', |
| 43 | + 'not_function' => '没有找到函数方法:', |
| 44 | + 'not_class' => '没有找到类:', |
| 45 | + 'not_class_func' => '没有找到类中的函数方法:', |
| 46 | + 'not_undefined' => '没有定义的方法:', |
| 47 | + 'not_open' => '打开文件不存在:', |
| 48 | + 'not_constant' => '未定义常量:', |
| 49 | + 'not_redeclare' => '重复声明:', |
| 50 | + 'not_convert_str' => '无法转换为字符:', |
| 51 | + ); |
| 52 | + |
| 53 | + /* |
| 54 | + * 声明模板用法 |
| 55 | + */ |
| 56 | + function __construct($e=array(),$files=''){ |
| 57 | + global $FOUNDPHP_LANG,$_GET; |
| 58 | + //设置语言 |
| 59 | + if (!empty($FOUNDPHP_LANG)){ |
| 60 | + $this->set_lang = $FOUNDPHP_LANG; |
| 61 | + } |
| 62 | + $this->tpl = $GLOBALS['tpl']; |
| 63 | + if (isset($GLOBALS['tpl'])){ |
| 64 | + $this->tpl->TemplateDir = dirname(__FILE__).'/class/foundphp/view/'; |
| 65 | + $this->tpl->RunType = 'Replace'; |
| 66 | + $this->tpl->CacheDir = ''; |
| 67 | + } |
| 68 | + |
| 69 | + switch($e['type']){ |
| 70 | + case 1://致命的运行时错误 |
| 71 | + //方法不存在 |
| 72 | + if (strstr($e['message'],'undefined function')){ |
| 73 | + $e['types'] = 11; |
| 74 | + $e['func'] = $this->lang['not_function'].preg_replace_callback("/.+Call.+function(\s*[a-zA-Z0-9\_\$\(\)]{2,100})(\s*.+|)/is",function($m=''){return trim($m[1]);},$e['message']); |
| 75 | + } |
| 76 | + //类不存在 |
| 77 | + if (strstr($e['message'],'Uncaught Error: Class')){ |
| 78 | + $e['types'] = 12; |
| 79 | + $e['func'] = $this->lang['not_class'].preg_replace_callback("/.+Class\s*\'([a-zA-Z0-9\_\$\(\)]{2,100})\'\s*not.+/is",function($m=''){return trim($m[1]);},$e['message']); |
| 80 | + } |
| 81 | + //类方法没找到 |
| 82 | + if (strstr($e['message'],'Call to a member function')){ |
| 83 | + $e['types'] = 13; |
| 84 | + $e['func'] = $this->lang['not_class_func'].preg_replace_callback("/.+function\s*([a-zA-Z0-9\_\$\(\)]{2,100})(\s*.+|)/is",function($m=''){return trim($m[1]);},$e['message']); |
| 85 | + } |
| 86 | + //类方法没找到 |
| 87 | + if (strstr($e['message'],'Class') && strstr($e['message'],'not found')){ |
| 88 | + $e['types'] = 14; |
| 89 | + $e['func'] = preg_replace_callback("/Class\s*([a-zA-Z0-9\_\$\(\)]{2,100})(\s*.+|)/is",function($m=''){return trim($m[1]);},$e['message']); |
| 90 | + if (strstr($e['func'],'not found in')){ |
| 91 | + $e['func'] = $this->lang['not_class_func'].preg_replace_callback("/.+(Class.+not found).+/is",function($m=''){return trim($m[1]);},$e['message']); |
| 92 | + } |
| 93 | + } |
| 94 | + //声明错误 |
| 95 | + if (strstr($e['message'],'Call to undefined method')){ |
| 96 | + $e['types'] = 14; |
| 97 | + $e['func'] = $this->lang['not_undefined'].preg_replace_callback("/.+undefined method\s*([a-zA-Z0-9\_\$\(\)\:]{2,100})(\s*.+|)/is",function($m=''){return trim($m[1]);},$e['message']); |
| 98 | + } |
| 99 | + if (isset($e['message']) && @(int)$e['types']<=0){ |
| 100 | + $e['types'] = 19; |
| 101 | + $e['func'] = $e['message']; |
| 102 | + |
| 103 | + } |
| 104 | + break; |
| 105 | + |
| 106 | + case 2: //运行时警告 (非致命错误) |
| 107 | + if (strstr($e['message'],'Failed opening')){ |
| 108 | + $e['types'] = 21; |
| 109 | + $e['func'] = $this->lang['not_open'].preg_replace_callback("/.+Failed opening\s*\'([a-zA-Z0-9\_\.]{2,100})\'\s*for.+/is",function($m=''){return trim($m[1]);},$e['message']); |
| 110 | + }elseif(strstr($e['message'],'Use of undefined constant')){ |
| 111 | + $e['types'] = 22; |
| 112 | + $e['func'] = $this->lang['not_constant'].preg_replace_callback("/Use of undefined constant\s*\'([a-zA-Z0-9\_\.]{2,100})\'\s*for.+/is",function($m=''){return trim($m[1]);},$e['message']); |
| 113 | + } |
| 114 | + break; |
| 115 | + case 4://编译时语法解析错误 |
| 116 | + if (strstr($e['message'],'syntax error, unexpected')){ |
| 117 | + $e['types'] = 41; |
| 118 | + $e['func'] = $e['message']; |
| 119 | + }else{ |
| 120 | + $e['types'] = 40; |
| 121 | + $e['func'] = $e['message']; |
| 122 | + } |
| 123 | + |
| 124 | + break; |
| 125 | + case 8://编译时语法解析错误 |
| 126 | + if (strstr($e['message'],'Undefined index')){ |
| 127 | + // $e['types'] = 81; |
| 128 | + // $e['func'] = $e['message']; |
| 129 | + } |
| 130 | + |
| 131 | + break; |
| 132 | + case 16://在PHP初始化启动过程中发生的致命错误 |
| 133 | + |
| 134 | + break; |
| 135 | + case 32://PHP初始化启动过程中发生的警告 |
| 136 | + |
| 137 | + break; |
| 138 | + case 64://致命编译时错误 |
| 139 | + //类方法没找到 |
| 140 | + if (strstr($e['message'],'Cannot redeclare')){ |
| 141 | + $e['types'] = 64; |
| 142 | + $e['func'] = $this->lang['not_redeclare'].preg_replace_callback("/.+redeclare\s*([a-zA-Z0-9\_\$\(\)]{2,100})(\s*.+|)/is",function($m=''){return trim($m[1]);},$e['message']); |
| 143 | + } |
| 144 | + if (strstr($e['message'],'Failed opening required')){ |
| 145 | + $e['types'] = 641; |
| 146 | + $e['func'] = $this->lang['not_open'].preg_replace_callback("/.+opening required\s*\'(.+)\' .+/is",function($m=''){print_r($m);return trim($m[1]);},$e['message']); |
| 147 | + } |
| 148 | + if (isset($e['message']) && (int)$e['types']<=0){ |
| 149 | + $e['types'] = 19; |
| 150 | + $e['func'] = $e['message']; |
| 151 | + |
| 152 | + } |
| 153 | + |
| 154 | + break; |
| 155 | + case 128://编译时警告 (非致命错误) |
| 156 | + |
| 157 | + break; |
| 158 | + case 2048://启用PHP对代码的修改建议 |
| 159 | + |
| 160 | + break; |
| 161 | + case 4096://可被捕捉的致命错误 |
| 162 | + if (strstr($e['message'],'could not be converted to string')){ |
| 163 | + $e['types'] = 4096; |
| 164 | + $e['func'] = $this->lang['not_convert_str'].preg_replace_callback("/.+of class\s*([a-zA-Z0-9\_\$\(\)]{2,100})(\s*.+|)could not be.+/is",function($m=''){return trim($m[1]);},$e['message']); |
| 165 | + } |
| 166 | + break; |
| 167 | + } |
| 168 | + $this->display($e); |
| 169 | + } |
| 170 | + |
| 171 | + function head($title){ |
| 172 | + $this->tpl->set_var( |
| 173 | + array( |
| 174 | + 'header_title' => $title |
| 175 | + ) |
| 176 | + ); |
| 177 | + $this->tpl->set_file('header'); |
| 178 | + $result = $this->tpl->r(); |
| 179 | + if (stristr(get_url(),'/install/index.php?a=')){ |
| 180 | + $result = str_replace('data/style/','../data/style/',$result); |
| 181 | + $result = str_replace('../../','../',$result); |
| 182 | + } |
| 183 | + echo $result; |
| 184 | + } |
| 185 | + |
| 186 | + //显示错误界面 |
| 187 | + function display($ary=array()){ |
| 188 | + if (@$ary['func']){ |
| 189 | + $content = ob_get_contents(); |
| 190 | + ob_end_clean(); |
| 191 | + if (stristr($ary['func'],'{FD}')){ |
| 192 | + $func_ext = explode('{FD}',$ary['func']); |
| 193 | + $ary['func']= $func_ext['0']; |
| 194 | + $ary['file']= $func_ext['1']; |
| 195 | + $ary['line']= ''; |
| 196 | + } |
| 197 | + |
| 198 | + //自动修复代码 |
| 199 | + if (strstr($ary['func'],'Undefined constant')||strstr($ary['func'],'Use of undefined constant')){ |
| 200 | + $this->fix_file(str_replace('\\','/',$ary['file'])); |
| 201 | + } |
| 202 | + //php8 版本解析 |
| 203 | + $ary['func'] = $this->analysis($ary['func'],$ary['file'],$ary['line']); |
| 204 | + |
| 205 | + //linux 下调试信息 |
| 206 | + if (!empty($GLOBALS['_SERVER']['PWD'])){ |
| 207 | + echo $this->lang['error_details'] .$this->error_intro($ary['types'])."\r\n"; |
| 208 | + echo $this->lang['error_details'] .$ary['func']."\r\n"; |
| 209 | + echo $this->lang['error_file'] .$ary['file']."\r\n"; |
| 210 | + if (!empty($ary['line'])){ |
| 211 | + echo $this->lang['error_line'] .$ary['line']."\r\n"; |
| 212 | + } |
| 213 | + }else{ |
| 214 | + //web 调试 |
| 215 | + $this->head('FoundPHP Error System'); |
| 216 | + $this->tpl->set_var( |
| 217 | + array( |
| 218 | + 'error_intro'=>$this->error_intro($ary['types']), |
| 219 | + 'func'=>$ary['func'], |
| 220 | + 'file'=>$ary['file'], |
| 221 | + 'line'=>$ary['line'], |
| 222 | + 'lang'=>$this->lang |
| 223 | + ) |
| 224 | + ); |
| 225 | + $this->tpl->set_file('display'); |
| 226 | + $this->tpl->p(); |
| 227 | + } |
| 228 | + if (!empty($ary['func'])){ |
| 229 | + $result .= date('Y-m-d H:i:s')." ".$ary['file'].(!empty($ary['line'])?" Line:".$ary['line']:'')."\r\n"; |
| 230 | + $result .= "Err:".$ary['func']."\r\n\r\n"; |
| 231 | + @file_put_contents(dirname(__DIR__).'/'.$GLOBALS['RAND_DIR'].'/log/'.dates(time(),'ymd').'_error.txt',strip_tags($result),FILE_APPEND); |
| 232 | + } |
| 233 | + exit; |
| 234 | + } |
| 235 | + exit; |
| 236 | + } |
| 237 | + |
| 238 | + //解析php8代码说明 |
| 239 | + function analysis($str='',$files='',$line=0){ |
| 240 | + if (stristr($str,'Stack trace:')){ |
| 241 | + //php 8 说明 |
| 242 | + $exp_str = explode('Stack trace:',$str); |
| 243 | + $exp_str['0'] = str_replace(' in '," in<br>",$exp_str['0']); |
| 244 | + $file_exp = explode('#',$exp_str['1']); |
| 245 | + $error_info = explode('):',$file_exp['1']); |
| 246 | + if ($this->set_lang!='en'){ |
| 247 | + $exp_str['0'] = str_replace('Uncaught Error:','<b>'.$this->lang['error_trace'].'</b>',$exp_str['0']); |
| 248 | + } |
| 249 | + $str = $exp_str['0']."<br><br><b>".$this->lang['error_from']."</b>".$error_info['1'].' '.str_replace('(',':',str_replace('0 ','<br>',$error_info['0'])); |
| 250 | + }elseif(stristr($str,'Use of undefined constant')){ |
| 251 | + //php7 说明 |
| 252 | + $str_ext = explode('-',$str); |
| 253 | + $error_id = str_replace('Use of undefined constant','',$str_ext['0']); |
| 254 | + if (!empty($error_id)){ |
| 255 | + $str = $this->lang['error_code'].$this->fix_file($files,$line).'<br>'.$this->lang['error_str'].$error_id.'<br>'.$this->lang['error_future']; |
| 256 | + } |
| 257 | + } |
| 258 | + return $str; |
| 259 | + } |
| 260 | + |
| 261 | + //修复错误文件 |
| 262 | + function fix_file($files='',$line=0){ |
| 263 | + if (is_file($files) && !strstr($files,'controller')){ |
| 264 | + $f = explode("\n",$this->tpl->reader($files)); |
| 265 | + if (!empty($line)){ |
| 266 | + return $f[($line-1)]; |
| 267 | + } |
| 268 | + foreach($f AS $k=>$v) { |
| 269 | + $result[$k] = $this->fix_line($v); |
| 270 | + } |
| 271 | + $this->tpl->writer($files,implode("\n",$result)); |
| 272 | + |
| 273 | + } |
| 274 | + } |
| 275 | + |
| 276 | + //修复错误标识的php文件 |
| 277 | + function fix_line($str=''){ |
| 278 | + if (!empty($str)){ |
| 279 | + //过滤单引号中的中括号 |
| 280 | + $str = preg_replace_callback(array('/(\'.+\')/is'),function ($m=''){return "<FoundFix>".base64_encode($m[1])."<FoundFIX>";},$str); |
| 281 | + //过滤SQL代码 |
| 282 | + $str = preg_replace_callback(array('/(".+")/is'),function ($m=''){return "<FoundFix>".base64_encode($m[1])."<FoundFIX>";},$str); |
| 283 | + //修复缺少标识的php代码 |
| 284 | + $fix_str = preg_replace_callback(array('/(\[([a-zA-Z0-9_]{1,32})\])/is'),function ($m=''){return "['".$m[2]."']";},$str); |
| 285 | + if ($fix_str!=$str){ |
| 286 | + $str = $fix_str; |
| 287 | + } |
| 288 | + $str = preg_replace_callback(array('/\<FoundFix\>(.+)\<FoundFIX\>/is'),function ($m=''){return base64_decode($m[1]);},$str); |
| 289 | + return $str; |
| 290 | + }else{ |
| 291 | + return $str; |
| 292 | + } |
| 293 | + } |
| 294 | + |
| 295 | + function error_intro($types=0){ |
| 296 | + switch($types){ |
| 297 | + case 11; |
| 298 | + $intro['cn'] = '开发代码中出现方法丢失或调用错误,请修正或采用系统下载更新。'; |
| 299 | + break; |
| 300 | + |
| 301 | + case 12; |
| 302 | + $intro['cn'] = '开发代码中存在声明Class错误,未引用类文件或声明错误。'; |
| 303 | + |
| 304 | + break; |
| 305 | + case 13; |
| 306 | + $intro['cn'] = '开发代码中调用Class中的方法缺失,检查是否拼写正确。'; |
| 307 | + |
| 308 | + break; |
| 309 | + case 14; |
| 310 | + $intro['cn'] = '没有找到声明类,大多没有引用类文件。'; |
| 311 | + |
| 312 | + break; |
| 313 | + case 19; |
| 314 | + $intro['cn'] = '建议根据[出错原因]修改代码。'; |
| 315 | + |
| 316 | + break; |
| 317 | + |
| 318 | + case 21; |
| 319 | + $intro['cn'] = '引用文件不存在或输入错误。'; |
| 320 | + |
| 321 | + break; |
| 322 | + |
| 323 | + case 22; |
| 324 | + $intro['cn'] = "应用数组PHP7.2以上需要增加单引号,例如:\$FoundPHP['good']"; |
| 325 | + break; |
| 326 | + |
| 327 | + case 41; |
| 328 | + $intro['cn'] = '代码行结束缺少;符号或缺少其他字符。'; |
| 329 | + |
| 330 | + break; |
| 331 | + |
| 332 | + case 64; |
| 333 | + $intro['cn'] = '调用文件出现相同名称的function,请排除不需要的方法或改名。'; |
| 334 | + |
| 335 | + break; |
| 336 | + |
| 337 | + case 641; |
| 338 | + $intro['cn'] = 'require 打开的文件目录不正确或文件不存在。'; |
| 339 | + |
| 340 | + break; |
| 341 | + case 4096; |
| 342 | + $intro['cn'] = '字符中不可以包含对象。'; |
| 343 | + |
| 344 | + break; |
| 345 | + |
| 346 | + } |
| 347 | + $intro['cn'] .= '<br>建议检查错误文件行号附近代码。'; |
| 348 | + if (!empty($intro['cn'])){ |
| 349 | + return $intro['cn']; |
| 350 | + } |
| 351 | + } |
| 352 | + |
| 353 | +} |
| 354 | + |
| 355 | + |
| 356 | + |
0 commit comments