[ Index ] |
|
Code source de e107 0.7.8 |
1 <?php 2 /* 3 + ----------------------------------------------------------------------------+ 4 | e107 website system 5 | 6 | ©Steve Dunstan 2001-2002 7 | http://e107.org 8 | jalist@e107.org 9 | 10 | Released under the terms and conditions of the 11 | GNU General Public License (http://gnu.org). 12 | 13 | $Source: /cvsroot/e107/e107_0.7/e107_handlers/db_debug_class.php,v $ 14 | $Revision: 1.19 $ 15 | $Date: 2006/12/05 09:54:57 $ 16 | $Author: mrpete $ 17 +----------------------------------------------------------------------------+ 18 */ 19 20 if (!defined('e107_INIT')) { exit; } 21 22 class e107_db_debug { 23 var $aSQLdetails = array(); // DB query analysis (in pieces for further analysis) 24 var $aDBbyTable = array(); 25 var $aOBMarks = array(0 => ''); // Track output buffer level at each time mark 26 var $aMarkNotes = array(); // Other notes can be added and output... 27 var $aTimeMarks = array(); // Overall time markers 28 var $curTimeMark = 'Start'; 29 var $nTimeMarks = 0; // Provide an array index for time marks. Stablizes 'current' function 30 var $aGoodQueries = array(); 31 var $aBadQueries = array(); 32 var $scbbcodes = array(); 33 var $scbcount; 34 var $deprecated_funcs = array(); 35 var $aLog = array(); // Generalized debug log (only seen during debug) 36 37 function e107_db_debug() { 38 global $eTimingStart; 39 40 $this->aTimeMarks[0]=array( 41 'Index' => 0, 42 'What' => 'Start', 43 '%Time' => 0, 44 '%DB Time' => 0, 45 '%DB Count' => 0, 46 'Time' => ($eTimingStart), 47 'DB Time' => 0, 48 'DB Count' => 0 49 ); 50 51 register_shutdown_function('e107_debug_shutdown'); 52 } 53 54 // 55 // Add your new Show function here so it will display in debug output! 56 // 57 function Show_All() 58 { 59 global $eTraffic; 60 61 $this->ShowIf('Debug Log', $this->Show_Log()); 62 $this->ShowIf('Traffic Counters', $eTraffic->Display()); 63 $this->ShowIf('Time Analysis', $this->Show_Performance()); 64 $this->ShowIf('SQL Analysis', $this->Show_SQL_Details()); 65 $this->ShowIf('Shortcodes / BBCode',$this->Show_SC_BB()); 66 $this->ShowIf('Paths', $this->Show_PATH()); 67 $this->ShowIf('Deprecated Function Usage', $this->Show_DEPRECATED()); 68 } 69 70 function ShowIf($title,$str) 71 { 72 global $ns; 73 74 if (!isset($ns)) { 75 echo "Why did ns go away?<br/>"; 76 $ns = new e107table; 77 } 78 79 if (strlen($str)) { 80 $ns->tablerender($title, $str); 81 } 82 } 83 84 function Mark_Time($sMarker) { // Should move to traffic_class? 85 $timeNow=microtime(); 86 $nMarks=++$this->nTimeMarks; 87 88 if (!strlen($sMarker)) { 89 $sMarker = "Mark not set"; 90 } 91 92 $this->aTimeMarks[$nMarks]=array( 93 'Index' => ($this->nTimeMarks), 94 'What' => $sMarker, 95 '%Time' => 0, 96 '%DB Time' => 0, 97 '%DB Count' => 0, 98 'Time' => $timeNow, 99 'DB Time' => 0, 100 'DB Count' => 0 101 ); 102 103 $this->aOBMarks[$nMarks]=ob_get_level().'('.ob_get_length().')'; 104 $this->curTimeMark=$sMarker; 105 106 // Add any desired notes to $aMarkNotes[$nMarks]... e.g. 107 //global $eTimingStart; 108 //$this->aMarkNotes[$nMarks] .= "verify start: ".$eTimingStart."<br/>"; 109 } 110 111 function Mark_Query($query, $rli, $origQryRes, $aTrace, $mytime, $curtable) { 112 global $sql; 113 114 // Explain the query, if possible... 115 list($qtype,$args) = explode(" ", ltrim($query), 2); 116 117 $nFields=0; 118 $bExplained = FALSE; 119 if (!strcasecmp($qtype,'SELECT') || !strcasecmp($qtype,'(SELECT')) { 120 $sQryRes=is_null($rli) ? mysql_query("EXPLAIN $query") : mysql_query("EXPLAIN $query", $rli); 121 122 if ($sQryRes) { // There's something to explain 123 $nFields = mysql_num_fields($sQryRes); 124 $bExplained = TRUE; 125 } 126 } else { 127 $sQryRes = $origQryRes; 128 $bExplained = FALSE; 129 $nFields=0; 130 } 131 132 // Record Basic query info 133 $sCallingFile=$aTrace[1]['file']; 134 $sCallingLine=$aTrace[1]['line']; 135 136 $t = &$this->aSQLdetails[$sql->db_QueryCount()]; 137 $t['marker']=$this->curTimeMark; 138 $t['caller']="$sCallingFile($sCallingLine)"; 139 $t['query']=$query; 140 $t['ok']=$sQryRes ? TRUE : FALSE; 141 $t['error']=$sQryRes ? '' : mysql_error(); 142 $t['nFields']=$nFields; 143 $t['time']=$mytime; 144 145 if ($bExplained) { 146 $bRowHeaders=FALSE; 147 while ($row = @mysql_fetch_assoc($sQryRes)) { 148 if (!$bRowHeaders) { 149 $bRowHeaders=TRUE; 150 $t['explain']="<tr><td class='forumheader3'><b>".implode("</b></td><td class='forumheader3'><b>", array_keys($row))."</b></td></tr>\n"; 151 } 152 153 $t['explain'] .= "<tr><td class='forumheader3'>".implode(" </td><td class='forumheader3'>", array_values($row))." </td></tr>\n"; 154 } 155 } else { 156 $t['explain'] = ''; 157 } 158 159 $this->aTimeMarks[$this->nTimeMarks]['DB Time'] += $mytime; 160 $this->aTimeMarks[$this->nTimeMarks]['DB Count']++; 161 162 if (array_key_exists($curtable, $this->aDBbyTable)) { 163 $this->aDBbyTable[$curtable]['DB Time'] += $mytime; 164 $this->aDBbyTable[$curtable]['DB Count']++; 165 } else { 166 $this->aDBbyTable[$curtable]['Table']=$curtable; 167 $this->aDBbyTable[$curtable]['%DB Time']=0; // placeholder 168 $this->aDBbyTable[$curtable]['%DB Count']=0; // placeholder 169 $this->aDBbyTable[$curtable]['DB Time']=$mytime; 170 $this->aDBbyTable[$curtable]['DB Count']=1; 171 } 172 } 173 174 function Show_SQL_Details() { 175 global $sql; 176 // 177 // Show stats from aSQLdetails array 178 // 179 $text=''; 180 $nQueries=$sql->db_QueryCount(); 181 182 if (!$nQueries) return $text; 183 184 // 185 // ALWAYS summarize query errors 186 // 187 $badCount=0; 188 $okCount=0; 189 190 foreach ($this->aSQLdetails as $cQuery) { 191 if ($cQuery['ok']) { 192 $okCount++; 193 } else { 194 $badCount++; 195 } 196 } 197 198 if ($badCount) { 199 $text .= "\n<table class='fborder'>\n"; 200 $text .= "<tr><td class='fcaption' colspan='2'><b>$badCount Query Errors!</b></td></tr>\n"; 201 $text .= "<tr><td class='fcaption'><b>Index</b></td><td class='fcaption'><b>Query / Error</b></td></tr>\n"; 202 203 foreach ($this->aSQLdetails as $idx => $cQuery) { 204 if (!$cQuery['ok']) { 205 $text .= "<tr><td class='forumheader3' rowspan='2' style='text-align:right'>{$idx} </td> 206 <td class='forumheader3'>".$cQuery['query']."</td></tr>\n<tr><td class='forumheader3'>".$cQuery['error']."</td></tr>\n"; 207 } 208 } 209 $text .= "\n</table><br/>\n"; 210 } 211 212 // 213 // Optionally list good queries 214 // 215 if ($okCount && E107_DBG_SQLQUERIES) { 216 $text .= "\n<table class='fborder'>\n"; 217 $text .= "<tr><td class='fcaption' colspan='3'><b>{$okCount[TRUE]} Good Queries</b></td></tr>\n"; 218 $text .= "<tr><td class='fcaption'><b>Index</b></td><td class='fcaption'><b>Qtime</b></td><td class='fcaption'><b>Query</b></td></tr>\n 219 <tr><td class='fcaption'> </td><td class='fcaption'><b>(msec)</b></td><td class='fcaption'> </td></tr>\n 220 "; 221 222 foreach ($this->aSQLdetails as $idx => $cQuery) { 223 if ($cQuery['ok']) { 224 $text .= "<tr><td class='forumheader3' style='text-align:right'>{$idx} </td> 225 <td class='forumheader3' style='text-align:right'>".number_format($cQuery['time'] * 1000.0, 4)." </td><td class='forumheader3'>".$cQuery['query'].'<br/>['.$cQuery['marker']." - ".$cQuery['caller']."]</td></tr>\n"; 226 } 227 } 228 $text .= "\n</table><br/>\n"; 229 } 230 231 232 // 233 // Optionally list query details 234 // 235 if (E107_DBG_SQLDETAILS) { 236 foreach ($this->aSQLdetails as $idx => $cQuery) { 237 $text .= "\n<table class='fborder' style='width: 100%;'>\n"; 238 $text .= "<tr><td class='forumheader3' colspan='".$cQuery['nFields']."'><b>".$idx.") Query:</b> [".$cQuery['marker']." - ".$cQuery['caller']."]<br/>".$cQuery['query']."</td></tr>\n"; 239 if (isset($cQuery['explain'])) { 240 $text .= $cQuery['explain']; 241 } 242 if (strlen($cQuery['error'])) { 243 $text .= "<tr><td class='forumheader3' ><b>Error in query:</b></td></tr>\n<tr><td class='forumheader3'>".$cQuery['error']."</td></tr>\n"; 244 } 245 246 $text .= "<tr><td class='forumheader3' colspan='".$cQuery['nFields']."'><b>Query time:</b> ".number_format($cQuery['time'] * 1000.0, 4).' (ms)</td></tr></table><br />'."\n"; 247 } 248 } 249 250 return $text; 251 } 252 253 function Show_Performance() { 254 // 255 // Stats by Time Marker 256 // 257 global $db_time; 258 global $sql; 259 global $eTimingStart, $eTimingStop, $eTraffic; 260 261 $this->Mark_Time('Stop'); 262 263 if (!E107_DBG_TIMEDETAILS) return ''; 264 265 $totTime=$eTraffic->TimeDelta($eTimingStart, $eTimingStop); 266 $text = "\n<table class='fborder'>\n"; 267 $bRowHeaders=FALSE; 268 reset($this->aTimeMarks); 269 $aSum=$this->aTimeMarks[0]; // create a template from the 'real' array 270 $aSum['Index']=''; 271 $aSum['What']='Total'; 272 $aSum['Time']=0; 273 $aSum['DB Count']=0; 274 $aSum['DB Time']=0; 275 276 while (list($tKey, $tMarker) = each($this->aTimeMarks)) { 277 if (!$bRowHeaders) { 278 // First time: emit headers 279 $bRowHeaders=TRUE; 280 $text .= "<tr><td class='fcaption' style='text-align:right'><b>".implode("</b> </td><td class='fcaption' style='text-align:right'><b>", array_keys($tMarker))."</b> </td><td class='fcaption' style='text-align:right'><b>OB Lev </b></td></tr>\n"; 281 $aUnits = $tMarker; 282 foreach ($aUnits as $key=>$val) { 283 switch ($key) { 284 case 'DB Time': 285 case 'Time': 286 $aUnits[$key] = '(msec)'; 287 break; 288 default: 289 $aUnits[$key] = ''; 290 break; 291 } 292 } 293 $aUnits['OB Lev'] = 'lev(buf bytes)'; 294 $text .= "<tr><td class='fcaption' style='text-align:right'><b>".implode("</b> </td><td class='fcaption' style='text-align:right'><b>", $aUnits)."</b> </td></tr>\n"; 295 } 296 297 if ($tMarker['What'] == 'Stop') { 298 $tMarker['Time']=' '; 299 $tMarker['%Time']=' '; 300 $tMarker['%DB Count']=' '; 301 $tMarker['%DB Time']=' '; 302 $tMarker['DB Time']=' '; 303 $tMarker['OB Lev']=$this->aOBMarks[$tKey]; 304 $tMarker['DB Count']=' '; 305 } else { 306 // Convert from start time to delta time, i.e. from now to next entry 307 $nextMarker=current($this->aTimeMarks); 308 $aNextT=$nextMarker['Time']; 309 $aThisT=$tMarker['Time']; 310 311 $thisDelta=$eTraffic->TimeDelta($aThisT, $aNextT); 312 $aSum['Time'] += $thisDelta; 313 $aSum['DB Time'] += $tMarker['DB Time']; 314 $aSum['DB Count'] += $tMarker['DB Count']; 315 $tMarker['Time']=number_format($thisDelta*1000.0, 1); 316 $tMarker['%Time']=$totTime ? number_format(100.0 * ($thisDelta / $totTime), 0) : 0; 317 $tMarker['%DB Count']=number_format(100.0 * $tMarker['DB Count'] / $sql->db_QueryCount(), 0); 318 $tMarker['%DB Time']=$db_time ? number_format(100.0 * $tMarker['DB Time'] / $db_time, 0) : 0; 319 $tMarker['DB Time']=number_format($tMarker['DB Time']*1000.0, 1); 320 $tMarker['OB Lev']=$this->aOBMarks[$tKey]; 321 } 322 $text .= "<tr><td class='forumheader3' >".implode(" </td><td class='forumheader3' style='text-align:right'>", array_values($tMarker))." </td></tr>\n"; 323 324 if (isset($this->aMarkNotes[$tKey])) { 325 $text .= "<tr><td class='forumheader3' > </td><td class='forumheader3' colspan='4'>"; 326 $text .= $this->aMarkNotes[$tKey]."</td></tr>\n"; 327 } 328 if ($tMarker['What'] == 'Stop') break; 329 } 330 331 $aSum['%Time']=$totTime ? number_format(100.0 * ($aSum['Time'] / $totTime), 0) : 0; 332 $aSum['%DB Time']=$db_time ? number_format(100.0 * ($aSum['DB Time'] / $db_time), 0) : 0; 333 $aSum['%DB Count']=($sql->db_QueryCount()) ? number_format(100.0 * ($aSum['DB Count'] / ($sql->db_QueryCount())), 0) : 0; 334 $aSum['Time']=number_format($aSum['Time']*1000.0, 1); 335 $aSum['DB Time']=number_format($aSum['DB Time']*1000.0, 1); 336 337 $text .= "<tr><td class='fcaption'><b>".implode("</b> </td><td class='fcaption' style='text-align:right'><b>", $aSum)."</b> </td><td class='fcaption'> </td></tr>\n"; 338 $text .= "\n</table><br/>\n"; 339 340 // 341 // Stats by Table 342 // 343 344 $text .= "\n<table class='fborder'>\n"; 345 346 $bRowHeaders=FALSE; 347 $aSum=$this->aDBbyTable['core']; // create a template from the 'real' array 348 $aSum['Table']='Total'; 349 $aSum['%DB Count']=0; 350 $aSum['%DB Time']=0; 351 $aSum['DB Time']=0; 352 $aSum['DB Count']=0; 353 354 foreach ($this->aDBbyTable as $curTable) { 355 if (!$bRowHeaders) { 356 $bRowHeaders=TRUE; 357 $text .= "<tr><td class='fcaption'><b>".implode("</b></td><td class='fcaption'><b>", array_keys($curTable))."</b></td></tr>\n"; 358 $aUnits = $curTable; 359 foreach ($aUnits as $key=>$val) { 360 switch ($key) { 361 case 'DB Time': 362 $aUnits[$key] = '(msec)'; 363 break; 364 default: 365 $aUnits[$key] = ''; 366 break; 367 } 368 } 369 $text .= "<tr><td class='fcaption' style='text-align:right'><b>".implode("</b> </td><td class='fcaption' style='text-align:right'><b>", $aUnits)."</b> </td></tr>\n"; 370 } 371 372 $aSum['DB Time'] += $curTable['DB Time']; 373 $aSum['DB Count'] += $curTable['DB Count']; 374 $curTable['%DB Count']=number_format(100.0 * $curTable['DB Count'] / $sql->db_QueryCount(), 0); 375 $curTable['%DB Time']=number_format(100.0 * $curTable['DB Time'] / $db_time, 0); 376 $curTable['DB Time']=number_format($curTable['DB Time']*1000.0, 1); 377 $text .= "<tr><td class='forumheader3'>".implode(" </td><td class='forumheader3' style='text-align:right'>", array_values($curTable))." </td></tr>\n"; 378 } 379 380 $aSum['%DB Time']=$db_time ? number_format(100.0 * ($aSum['DB Time'] / $db_time), 0) : 0; 381 $aSum['%DB Count']=($sql->db_QueryCount()) ? number_format(100.0 * ($aSum['DB Count'] / ($sql->db_QueryCount())), 0) : 0; 382 $aSum['DB Time']=number_format($aSum['DB Time']*1000.0, 1); 383 $text .= "<tr><td class='fcaption'>".implode(" </td><td class='fcaption' style='text-align:right'>", array_values($aSum))." </td></tr>\n"; 384 $text .= "\n</table><br/>\n"; 385 386 return $text; 387 } 388 389 function logDeprecated(){ 390 391 $back_trace = debug_backtrace(); 392 393 print_r($back_trace); 394 395 $this->deprecated_funcs[] = array ( 396 'func' => (isset($back_trace[1]['type']) && ($back_trace[1]['type'] == '::' || $back_trace[1]['type'] == '->') ? $back_trace[1]['class'].$back_trace[1]['type'].$back_trace[1]['function'] : $back_trace[1]['function']), 397 'file' => $back_trace[1]['file'], 398 'line' => $back_trace[1]['line'] 399 ); 400 401 } 402 403 function logCode($type, $code, $parm, $postID) 404 { 405 if (!E107_DBG_BBSC) 406 { 407 return FALSE; 408 } 409 $this -> scbbcodes[$this -> scbcount]['type'] = $type; 410 $this -> scbbcodes[$this -> scbcount]['code'] = $code; 411 $this -> scbbcodes[$this -> scbcount]['parm'] = $parm; 412 $this -> scbbcodes[$this -> scbcount]['postID'] = $postID; 413 $this -> scbcount ++; 414 } 415 416 function Show_SC_BB() 417 { 418 if (!E107_DBG_BBSC) 419 { 420 return FALSE; 421 } 422 $text = "<table class='fborder' style='width: 100%'> 423 <tr><td class='fcaption' colspan='4'><b>Shortcode / BBCode</b></td></tr> 424 <tr> 425 <td class='fcaption' style='width: 10%;'>Type</td> 426 <td class='fcaption' style='width: 10%;'>Code</td> 427 <td class='fcaption' style='width: 10%;'>Parm</td> 428 <td class='fcaption' style='width: 10%;'>Post ID</td> 429 </tr>\n"; 430 431 foreach($this -> scbbcodes as $codes) 432 { 433 $text .= "<tr> 434 <td class='forumheader3' style='width: 10%;'>".($codes['type'] == 1 ? "BBCode" : "Shortcode")."</td> 435 <td class='forumheader3' style='width: 10%;'>".(isset($codes['code']) ? $codes['code'] : " ")."</td> 436 <td class='forumheader3' style='width: 10%;'>".($codes['parm'] ? $codes['parm'] : " ")."</td> 437 <td class='forumheader3' style='width: 10%;'>".($codes['postID'] ? $codes['postID'] : " ")."</td> 438 </tr>\n"; 439 } 440 $text .= "</table>"; 441 return $text; 442 } 443 444 function Show_PATH() 445 { 446 if (!E107_DBG_PATH) 447 { 448 return FALSE; 449 } 450 global $e107; 451 $text = "<table class='fborder' style='width: 100%'> 452 <tr><td class='fcaption' colspan='4'><b>Paths</b></td></tr> 453 <tr> 454 <td class='forumheader3'>\n"; 455 456 ob_start(); 457 echo "<pre>"; print_r($e107); echo "</pre>"; 458 $text .= ob_get_contents(); 459 ob_end_clean(); 460 461 $text .= "e_HTTP: '".e_HTTP."'<br />"; 462 $text .= "e_BASE: '".e_BASE."'<br />"; 463 $text .= "\$_SERVER['PHP_SELF']: '".$_SERVER['PHP_SELF']."'<br />"; 464 $text .= "\$_SERVER['DOCUMENT_ROOT']: '".$_SERVER['DOCUMENT_ROOT']."'<br />"; 465 $text .= "\$_SERVER['HTTP_HOST']: '".$_SERVER['HTTP_HOST']."'<br />"; 466 467 $text .= "</td></tr></table>"; 468 return $text; 469 } 470 471 472 function Show_DEPRECATED(){ 473 if (!E107_DBG_DEPRECATED){ 474 return FALSE; 475 } else { 476 $text = "<table class='fborder' style='width: 100%'> 477 <tr><td class='fcaption' colspan='4'><b>The following deprecated functions were used:</b></td></tr> 478 <tr> 479 <td class='fcaption' style='width: 10%;'>Function</td> 480 <td class='fcaption' style='width: 10%;'>File</td> 481 <td class='fcaption' style='width: 10%;'>Line</td> 482 </tr>\n"; 483 484 foreach($this->deprecated_funcs as $funcs) 485 { 486 $text .= "<tr> 487 <td class='forumheader3' style='width: 10%;'>{$funcs['func']}()</td> 488 <td class='forumheader3' style='width: 10%;'>{$funcs['file']}</td> 489 <td class='forumheader3' style='width: 10%;'>{$funcs['line']}</td> 490 </tr>\n"; 491 } 492 $text .= "</table>"; 493 return $text; 494 } 495 } 496 497 // 498 // Simple debug-level 'console' log 499 // Record a "nice" debug message with 500 // $db_debug->log("message"); 501 // 502 function log($message,$TraceLev=1) 503 { 504 if (!E107_DBG_BASIC){ 505 return FALSE; 506 } 507 if ($TraceLev) 508 { 509 $bt = debug_backtrace(); 510 $this->aLog[] = array ( 511 'Message' => $message, 512 'Function' => (isset($bt[$TraceLev]['type']) && ($bt[$TraceLev]['type'] == '::' || $bt[$TraceLev]['type'] == '->') ? $bt[$TraceLev]['class'].$bt[$TraceLev]['type'].$bt[$TraceLev]['function'].'()' : $bt[$TraceLev]['function']).'()', 513 'File' => $bt[$TraceLev]['file'], 514 'Line' => $bt[$TraceLev]['line'] 515 ); 516 } else { 517 $this->aLog[] = array ( 518 'Message' => $message, 519 'Function' => '', 520 'File' => '', 521 'Line' => '' 522 ); 523 } 524 } 525 526 function Show_Log(){ 527 if (!E107_DBG_BASIC || !count($this->aLog)){ 528 return FALSE; 529 } 530 // 531 // Dump the debug log 532 // 533 534 $text .= "\n<table class='fborder'>\n"; 535 536 $bRowHeaders=FALSE; 537 538 foreach ($this->aLog as $curLog) 539 { 540 if (!$bRowHeaders) { 541 $bRowHeaders=TRUE; 542 $text .= "<tr class='fcaption'><td><b>".implode("</b></td><td><b>", array_keys($curLog))."</b></td></tr>\n"; 543 } 544 545 $text .= "<tr class='forumheader3'><td>".implode(" </td><td>", array_values($curLog))." </td></tr>\n"; 546 } 547 548 $text .= "</table><br/>\n"; 549 550 return $text; 551 } 552 } 553 554 function e107_debug_shutdown() 555 { 556 global $error_handler,$e107_Clean_Exit,$In_e107_Footer,$ADMIN_DIRECTORY; 557 if (isset($e107_Clean_Exit)) return; 558 559 if (!isset($In_e107_Footer)) 560 { 561 if (defset('ADMIN_AREA')) 562 { 563 $filewanted=realpath(dirname(__FILE__)).'/../'.$ADMIN_DIRECTORY.'footer.php'; 564 require_once($filewanted); 565 } else if (defset('USER_AREA')) 566 { 567 $filewanted=realpath(dirname(__FILE__)).'/../'.FOOTERF; 568 require_once($filewanted); 569 } 570 } 571 // 572 // Error while in the footer, or during startup, or during above processing 573 // 574 if (isset($e107_Clean_Exit)) return; // We've now sent a footer... 575 576 // echo isset($In_e107_Footer) ? "In footer" : "In startup".'<br>'; 577 578 while (ob_get_level() > 0) { 579 ob_end_flush(); 580 } 581 if (isset($error_handler)) 582 { 583 echo "<br /><div><h3>PHP Errors:</h3><br />".$error_handler->return_errors()."</div>\n"; 584 } else { 585 echo "<b>e107 Shutdown while no error_handler available!</b>"; 586 } 587 echo "</body></html>"; 588 } 589 590 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Apr 1 01:23:32 2007 | par Balluche grâce à PHPXref 0.7 |