Documentation TYPO3 par Ameos |
00001 <?php 00002 /************************************************ 00003 ** Title.........: PHP4+ Debug Helper 00004 ** Author........: Thomas Sch��ler <code at atomar dot de> 00005 ** Filename......: debuglib.php(s) 00006 ** Last changed..: 03.04.2004 12:09 00007 ** License.......: Free to use. Postcardware ;) 00008 ** 00009 ************************************************* 00010 ** 00011 ** Functions in this library: 00012 ** 00013 ** print_a( array array [,bool show object vars] [,int returnmode] ) 00014 ** 00015 ** prints arrays in a readable, understandable form. 00016 ** if mode is defined the function returns the output instead of 00017 ** printing it to the browser 00018 ** 00019 ** print_a( $array, #, 1 ) shows also object properties 00020 ** print_a( $array, 1, # ) returns the table as a string instead of printing it to the output buffer 00021 ** print_a( $array, 2, # ) opens the table in a new window. 00022 ** !NEW! print_a($array, string, #) opens the output in individual windows indentied by the string. 00023 ** print_a( $array, 3, # ) opens a new browser window with a serialized version of your array (save as a textfile and can it for later use ;). 00024 ** 00025 ** show_vars( [bool verbose] [, bool show_object_vars ] [, int limit] ) 00026 ** 00027 ** use this function on the bottom of your script to see all 00028 ** superglobals and global variables in your script in a nice 00029 ** formated way 00030 ** 00031 ** show_vars() without parameter shows $_GET, $_POST, $_SESSION, 00032 ** $_FILES and all global variables you've defined in your script 00033 ** 00034 ** show_vars(1) shows $_SERVER and $_ENV in addition 00035 ** show_vars(#,1) shows also object properties 00036 ** show_vars(#, #, 15) shows only the first 15 entries in a numerical keyed array (or an array with more than 50 entries) ( standard is 5 ) 00037 ** show_vars(#, #, 0) shows all entries 00038 ** 00039 ** 00040 ** 00041 ** ** print_result( result_handle ) ** 00042 ** prints a mysql_result set returned by mysql_query() as a table 00043 ** this function is work in progress! use at your own risk 00044 ** 00045 ** 00046 ** Happy debugging and feel free to email me your comments. 00047 ** 00048 ** 00049 ** 00050 ** History: (starting at 2003-02-24) 00051 ** 00052 ** - added tooltips to the td's showing the type of keys and values (thanks Itomic) 00053 ** 2003-07-16 00054 ** - pre() function now trims trailing tabulators 00055 ** 2003-08-01 00056 ** - silly version removed.. who needs a version for such a thing ;) 00057 ** 2003-09-24 00058 ** - changed the parameters of print_a() a bit 00059 ** see above 00060 ** - addet the types NULL and bolean to print_a() 00061 ** - print_a() now replaces trailing spaces in string values with red underscores 00062 ** 2003-09-24 (later that day ;) 00063 ** - oops.. fixed the print_a() documentation.. parameter order was wrong 00064 ** - added mode 3 to the second parameter 00065 ** 2003-09-25 00066 ** - added a limit parameter to the show_vars() and print_a() functions 00067 ** default for show_vars() is 5 00068 ** show_vars(#,#, n) changes that (0 means show all entries) 00069 ** print_a() allways shows all entries by default 00070 ** print_a(#,#,#, n) changes that 00071 ** 00072 ** this parameter is used to limit the output of arrays with a numerical index (like long lists of similiar elements) 00073 ** i added this option for performance reasons 00074 ** it has no effect on arrays where one ore more keys are not number-strings 00075 ** 2003-09-27 00076 ** - reworked the pre() and _remove_exessive_leading_tabs() functions 00077 ** they now work like they should :) 00078 ** - some cosmetic changes 00079 ** 2003-10-28 00080 ** - fixed multiline string display 00081 ** 2003-11-14 00082 ** - argh! uploaded the wrong version :/ ... fixed.. sorry 00083 ** 2003-11-16 00084 ** - fixed a warning triggered by _only_numeric_keys() 00085 ** thanx Peter Valdemar :) 00086 ** - fixed a warning when print_a was called directly on an object 00087 ** thanx Hilton :) 00088 ** 2003-12-01 00089 ** - added slashes in front of the print_a(#,3) output 00090 ** 2004-03-17 00091 ** - fixed a problem when print_a(#,2) was called on an array containing newlines 00092 ** 2004-03-26 00093 ** - added a variation of mode 2 for print_a(). 00094 ** when a string is passed as the second parameter, a new window with the string as prefix gets opened for every differend string.. #TODO_COMMENT# 00095 ************************************************/ 00096 00097 00098 # This file must be the first include on your page. 00099 00100 /* used for tracking of generation-time */ 00101 { 00102 $MICROTIME_START = microtime(); 00103 @$GLOBALS_initial_count = count($GLOBALS); 00104 } 00105 00106 /************************************************ 00107 ** print_a class and helper function 00108 ** prints out an array in a more readable way 00109 ** than print_r() 00110 ** 00111 ** based on the print_a() function from 00112 ** Stephan Pirson (Saibot) 00113 ************************************************/ 00114 00115 class Print_a_class { 00116 00117 # this can be changed to TRUE if you want 00118 var $look_for_leading_tabs = FALSE; 00119 00120 var $output; 00121 var $iterations; 00122 var $key_bg_color = '1E32C8'; 00123 var $value_bg_color = 'DDDDEE'; 00124 var $fontsize = '8pt'; 00125 var $keyalign = 'center'; 00126 var $fontfamily = 'Verdana'; 00127 var $show_object_vars; 00128 var $limit; 00129 00130 // function Print_a_class() {} 00131 00132 # recursive function! 00133 00134 /* this internal function looks if the given array has only numeric values as */ 00135 function _only_numeric_keys( $array ) { 00136 $test = TRUE; 00137 if (is_array($array)) { 00138 00139 foreach( array_keys( $array ) as $key ) { 00140 if( !is_numeric( $key ) ) $test = FALSE; /* #TODO# */ 00141 } 00142 return $test; 00143 } else { 00144 00145 return FALSE; 00146 00147 } 00148 00149 00150 } 00151 00152 function _handle_whitespace( $string ) { 00153 $string = str_replace(' ', ' ', $string); 00154 $string = preg_replace(array('/ $/', '/^ /'), '<span style="color:red;">_</span>', $string); /* replace spaces at the start/end of the STRING with red underscores */ 00155 $string = preg_replace('/\t/', ' <span style="border-bottom:#'.$this->value_bg_color.' solid 1px;"> </span>', $string); /* replace tabulators with '_ _' */ 00156 return $string; 00157 } 00158 00159 function print_a($array, $iteration = FALSE, $key_bg_color = FALSE) { 00160 $key_bg_color or $key_bg_color = $this->key_bg_color; 00161 00162 # lighten up the background color for the key td's =) 00163 if( $iteration ) { 00164 for($i=0; $i<6; $i+=2) { 00165 $c = substr( $key_bg_color, $i, 2 ); 00166 $c = hexdec( $c ); 00167 ( $c += 15 ) > 255 and $c = 255; 00168 isset($tmp_key_bg_color) or $tmp_key_bg_color = ''; 00169 $tmp_key_bg_color .= sprintf( "%02X", $c ); 00170 } 00171 $key_bg_color = $tmp_key_bg_color; 00172 } 00173 00174 # build a single table ... may be nested 00175 $this->output .= '<table style="border:none;" cellspacing="1">'; 00176 $only_numeric_keys = ($this->_only_numeric_keys( $array ) || count( $array ) > 50); 00177 $i = 0; 00178 foreach( $array as $key => $value ) { 00179 00180 if( $only_numeric_keys && $this->limit && $this->limit == $i++ ) break; /* if print_a() was called with a fourth parameter #TODO# */ 00181 00182 $value_style_box = 'color:black;'; 00183 $key_style = 'color:white;'; 00184 00185 $type = gettype( $value ); 00186 # print $type.'<br />'; 00187 00188 # change the color and format of the value and set the values title 00189 $type_title = $type; 00190 $value_style_content = ''; 00191 switch( $type ) { 00192 case 'array': 00193 if( empty( $value ) ) $type_title = 'empty array'; 00194 break; 00195 00196 case 'object': 00197 $key_style = 'color:#FF9B2F;'; 00198 break; 00199 00200 case 'integer': 00201 $value_style_box = 'color:green;'; 00202 break; 00203 00204 case 'double': 00205 $value_style_box = 'color:blue;'; 00206 break; 00207 00208 case 'boolean': 00209 if( $value == TRUE ) { 00210 $value_style_box = 'color:#D90081;'; 00211 } else { 00212 $value_style_box = 'color:#84009F;'; 00213 } 00214 break; 00215 00216 case 'NULL': 00217 $value_style_box = 'color:darkorange;'; 00218 break; 00219 00220 case 'string': 00221 if( $value == '' ) { 00222 00223 $value_style_box = 'color:darkorange;'; 00224 $value = "''"; 00225 $type_title = 'empty string'; 00226 00227 } else { 00228 00229 $value_style_box = 'color:black;'; 00230 $value = htmlspecialchars( $value ); 00231 if( $this->look_for_leading_tabs && _check_for_leading_tabs( $value ) ) { 00232 $value = _remove_exessive_leading_tabs( $value ); 00233 } 00234 $value = $this->_handle_whitespace( $value ); 00235 $value = nl2br($value); 00236 00237 /* use different color for string background */ 00238 if(strstr($value, "\n")) $value_style_content = 'background:#ECEDFE;'; 00239 00240 } 00241 break; 00242 } 00243 00244 $this->output .= '<tr>'; 00245 $this->output .= '<td nowrap="nowrap" align="'.$this->keyalign.'" style="padding:0px 3px 0px 3px;background-color:#'.$key_bg_color.';'.$key_style.';font:bold '.$this->fontsize.' '.$this->fontfamily.';" title="'.gettype( $key ).'['.$type_title.']">'; 00246 $this->output .= $this->_handle_whitespace( $key ); 00247 $this->output .= '</td>'; 00248 $this->output .= '<td nowrap="nowrap" style="background-color:#'.$this->value_bg_color.';font: '.$this->fontsize.' '.$this->fontfamily.'; color:black;">'; 00249 00250 00251 # value output 00252 if($type == 'array' && preg_match('/#RAS/', $key) ) { /* only used for special recursive array constructs which i use sometimes */ 00253 $this->output .= '<div style="'.$value_style_box.'">recursion!</div>'; 00254 } elseif($type == 'array') { 00255 if( ! empty( $value ) ) { 00256 $this->print_a( $value, TRUE, $key_bg_color ); 00257 } else { 00258 $this->output .= '<span style="color:darkorange;">[]</span>'; 00259 } 00260 } elseif($type == 'object') { 00261 if( $this->show_object_vars ) { 00262 $this->print_a( get_object_vars( $value ), TRUE, $key_bg_color ); 00263 } else { 00264 $this->output .= '<div style="'.$value_style_box.'">OBJECT</div>'; 00265 } 00266 } elseif($type == 'boolean') { 00267 $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'">'.($value ? 'TRUE' : 'FALSE').'</div>'; 00268 } elseif($type == 'NULL') { 00269 $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'">NULL</div>'; 00270 } else { 00271 $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'"><span style="'.$value_style_content.'">'.$value.'</span></div>'; 00272 } 00273 00274 $this->output .= '</td>'; 00275 $this->output .= '</tr>'; 00276 } 00277 00278 $entry_count = count( $array ); 00279 $skipped_count = $entry_count - $this->limit; 00280 00281 if( $only_numeric_keys && $this->limit && count($array) > $this->limit) { 00282 $this->output .= '<tr title="showing '.$this->limit.' of '.$entry_count.' entries in this array"><td style="text-align:right;color:darkgray;background-color:#'.$key_bg_color.';font:bold '.$this->fontsize.' '.$this->fontfamily.';">...</td><td style="background-color:#'.$this->value_bg_color.';font:'.$this->fontsize.' '.$this->fontfamily.';color:darkgray;">['.$skipped_count.' skipped]</td></tr>'; 00283 } 00284 $this->output .= '</table>'; 00285 } 00286 } 00287 00288 # helper function.. calls print_a() inside the print_a_class 00289 function print_a( $array, $mode = 0, $show_object_vars = FALSE, $limit = FALSE ) { 00290 $output = ''; 00291 00292 if( is_array( $array ) or is_object( $array ) ) { 00293 00294 if( empty( $array ) ) { 00295 $output .= '<span style="color:red;font-size:small;">print_a( empty array )</span>'; 00296 } 00297 00298 $pa = &new Print_a_class; 00299 $show_object_vars and $pa->show_object_vars = TRUE; 00300 if( $limit ) { 00301 $pa->limit = $limit; 00302 // $output .= '<span style="color:red;">showing only '.$limit.' entries for arrays with numeric keys</span>'; 00303 } 00304 00305 if ( is_object($array) ) { 00306 00307 $pa->print_a( get_object_vars($array) ); 00308 00309 } else { 00310 00311 $pa->print_a( $array ); 00312 } 00313 00314 # $output = $pa->output; unset($pa); 00315 $output .= $pa->output; 00316 } else { 00317 $output .= '<span style="color:red;font-size:small;">print_a( '.gettype( $array ).' )</span>'; 00318 } 00319 00320 if($mode === 0 || $mode == NULL || $mode == FALSE) { 00321 print $output; 00322 return TRUE; 00323 } 00324 00325 if($mode == 1) { 00326 return $output; 00327 } 00328 00329 if(is_string($mode) || $mode == 2 ) { 00330 $debugwindow_origin = $_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]; 00331 print ' 00332 <script type="text/javascript" language="JavaScript"> 00333 var debugwindow; 00334 debugwindow = window.open("", "T_'.md5($_SERVER['HTTP_HOST']).(is_string($mode) ? $mode : '').'", "menubar=no,scrollbars=yes,resizable=yes,width=640,height=480"); 00335 debugwindow.document.open(); 00336 debugwindow.document.write("'.str_replace(array("\r\n", "\n", "\r"), '\n', addslashes($output)).'"); 00337 debugwindow.document.close(); 00338 debugwindow.document.title = "'.(is_string($mode) ? "($mode)" : '').' Debugwindow for : http://'.$debugwindow_origin.'"; 00339 debugwindow.focus(); 00340 </script> 00341 '; 00342 } 00343 00344 if($mode == 3) { 00345 print ' 00346 <script type="text/javascript" language="JavaScript"> 00347 var debugwindow; 00348 debugwindow = window.open("", "S_'.md5($_SERVER['HTTP_HOST']).'", "menubar=yes,scrollbars=yes,resizable=yes,width=640,height=480"); 00349 debugwindow.document.open(); 00350 debugwindow.document.write("unserialize(\''.str_replace("'", "\\'", addslashes( str_replace(array("\r\n", "\n", "\r"), '\n', serialize($array) ) ) ).'\');"); 00351 debugwindow.document.close(); 00352 debugwindow.document.title = "Debugwindow for : http://'.$debugwindow_origin.'"; 00353 debugwindow.focus(); 00354 </script> 00355 '; 00356 } 00357 00358 } 00359 00360 00361 // shows mysql-result as a table.. # not ready yet :( 00362 function print_result($RESULT) { 00363 00364 if(!$RESULT) return; 00365 00366 00367 if(mysql_num_rows($RESULT) < 1) return; 00368 $fieldcount = mysql_num_fields($RESULT); 00369 00370 for($i=0; $i<$fieldcount; $i++) { 00371 $tables[mysql_field_table($RESULT, $i)]++; 00372 } 00373 00374 print ' 00375 <style type="text/css"> 00376 .rs_tb_th { 00377 font-family: Verdana; 00378 font-size:9pt; 00379 font-weight:bold; 00380 color:white; 00381 } 00382 .rs_f_th { 00383 font-family:Verdana; 00384 font-size:7pt; 00385 font-weight:bold; 00386 color:white; 00387 } 00388 .rs_td { 00389 font-family:Verdana; 00390 font-size:7pt; 00391 } 00392 </style> 00393 <script type="text/javascript" language="JavaScript"> 00394 var lastID; 00395 function highlight(id) { 00396 if(lastID) { 00397 lastID.style.color = "#000000"; 00398 lastID.style.textDecoration = "none"; 00399 } 00400 tdToHighlight = document.getElementById(id); 00401 tdToHighlight.style.color ="#FF0000"; 00402 tdToHighlight.style.textDecoration = "underline"; 00403 lastID = tdToHighlight; 00404 } 00405 </script> 00406 '; 00407 00408 print '<table bgcolor="#000000" cellspacing="1" cellpadding="1">'; 00409 00410 print '<tr>'; 00411 foreach($tables as $tableName => $tableCount) { 00412 $col == '0054A6' ? $col = '003471' : $col = '0054A6'; 00413 print '<th colspan="'.$tableCount.'" class="rs_tb_th" style="background-color:#'.$col.';">'.$tableName.'</th>'; 00414 } 00415 print '</tr>'; 00416 00417 print '<tr>'; 00418 for($i=0;$i < mysql_num_fields($RESULT);$i++) { 00419 $FIELD = mysql_field_name($RESULT, $i); 00420 $col == '0054A6' ? $col = '003471' : $col = '0054A6'; 00421 print '<td align="center" bgcolor="#'.$col.'" class="rs_f_th">'.$FIELD.'</td>'; 00422 } 00423 print '</tr>'; 00424 00425 mysql_data_seek($RESULT, 0); 00426 00427 while($DB_ROW = mysql_fetch_array($RESULT, MYSQL_NUM)) { 00428 $pointer++; 00429 if($toggle) { 00430 $col1 = "E6E6E6"; 00431 $col2 = "DADADA"; 00432 } else { 00433 $col1 = "E1F0FF"; 00434 $col2 = "DAE8F7"; 00435 } 00436 $toggle = !$toggle; 00437 print '<tr id="ROW'.$pointer.'" onMouseDown="highlight(\'ROW'.$pointer.'\');">'; 00438 foreach($DB_ROW as $value) { 00439 $col == $col1 ? $col = $col2 : $col = $col1; 00440 print '<td valign="top" bgcolor="#'.$col.'" class="rs_td" nowrap>'.nl2br($value).'</td>'; 00441 } 00442 print '</tr>'; 00443 } 00444 print '</table>'; 00445 mysql_data_seek($RESULT, 0); 00446 } 00447 00448 00449 ###################### 00450 # reset the millisec timer 00451 # 00452 function reset_script_runtime() { 00453 $GLOBALS['MICROTIME_START'] = microtime(); 00454 } 00455 00456 00457 ###################### 00458 # function returns the milliseconds passed 00459 # 00460 function script_runtime() { 00461 $MICROTIME_END = microtime(); 00462 $MICROTIME_START = explode(' ', $GLOBALS['MICROTIME_START']); 00463 $MICROTIME_END = explode(' ', $MICROTIME_END); 00464 $GENERATIONSEC = $MICROTIME_END[1] - $MICROTIME_START[1]; 00465 $GENERATIONMSEC = $MICROTIME_END[0] - $MICROTIME_START[0]; 00466 $GENERATIONTIME = substr($GENERATIONSEC + $GENERATIONMSEC, 0, 8); 00467 00468 return (float) $GENERATIONTIME; 00469 } 00470 00471 00472 ###################### 00473 # function shows all superglobals and script defined global variables 00474 # show_vars() without the first parameter shows all superglobals except $_ENV and $_SERVER 00475 # show_vars(1) shows all 00476 # show_vars(#,1) shows object properties in addition 00477 # 00478 function show_vars($show_all_vars = FALSE, $show_object_vars = FALSE, $limit = 5) { 00479 if($limit === 0) $limit = FALSE; 00480 00481 function _script_globals() { 00482 global $GLOBALS_initial_count; 00483 00484 $varcount = 0; 00485 00486 foreach($GLOBALS as $GLOBALS_current_key => $GLOBALS_current_value) { 00487 if(++$varcount > $GLOBALS_initial_count) { 00488 /* die wollen wir nicht! */ 00489 if ($GLOBALS_current_key != 'HTTP_SESSION_VARS' && $GLOBALS_current_key != '_SESSION') { 00490 $script_GLOBALS[$GLOBALS_current_key] = $GLOBALS_current_value; 00491 } 00492 } 00493 } 00494 00495 unset($script_GLOBALS['GLOBALS_initial_count']); 00496 return $script_GLOBALS; 00497 } 00498 00499 if(isset($GLOBALS['no_vars'])) return; 00500 00501 $script_globals = _script_globals(); 00502 print ' 00503 <style type="text/css" media="screen"> 00504 .vars-container { 00505 font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif; 00506 font-size: 8pt; 00507 padding:5px; 00508 } 00509 .varsname { 00510 font-weight:bold; 00511 } 00512 .showvars { 00513 background:white; 00514 border-style:dotted; 00515 border-width:1px; 00516 padding:2px; 00517 font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif; 00518 font-size:10pt; 00519 font-weight:bold;" 00520 } 00521 </style> 00522 <style type="text/css" media="print"> 00523 .showvars { 00524 display:none; 00525 visibility:invisible; 00526 } 00527 </style> 00528 '; 00529 00530 print '<br /> 00531 <div class="showvars"> 00532 DEBUG <span style="color:red;font-weight:normal;font-size:9px;">(runtime: '.script_runtime().' sec)</span> 00533 '; 00534 00535 $vars_arr['script_globals'] = array('global script variables', '#7ACCC8'); 00536 $vars_arr['_GET'] = array('$_GET', '#7DA7D9'); 00537 $vars_arr['_POST'] = array('$_POST', '#F49AC1'); 00538 $vars_arr['_FILES'] = array('$_FILES', '#82CA9C'); 00539 $vars_arr['_SESSION'] = array('$_SESSION', '#FCDB26'); 00540 $vars_arr['_COOKIE'] = array('$_COOKIE', '#A67C52'); 00541 00542 if($show_all_vars) { 00543 $vars_arr['_SERVER'] = array('SERVER', '#A186BE'); 00544 $vars_arr['_ENV'] = array('ENV', '#7ACCC8'); 00545 } 00546 00547 foreach($vars_arr as $vars_name => $vars_data) { 00548 if($vars_name != 'script_globals') global $$vars_name; 00549 if($$vars_name) { 00550 print '<div class="vars-container" style="background-color:'.$vars_data[1].';"><span class="varsname">'.$vars_data[0].'</span><br />'; 00551 print_a($$vars_name, NULL, $show_object_vars, $limit); 00552 print '</div>'; 00553 } 00554 } 00555 print '</div>'; 00556 } 00557 00558 00559 ###################### 00560 # function prints/returns strings wrapped between <pre></pre> 00561 # 00562 function pre( $string, $return_mode = FALSE, $tabwidth = 3 ) { 00563 $tab = str_repeat(' ', $tabwidth); 00564 $string = preg_replace('/\t+/em', "str_repeat( ' ', strlen('\\0') * $tabwidth );", $string); /* replace all tabs with spaces */ 00565 00566 $out = '<pre>'.$string."</pre>\n"; 00567 00568 if($return_mode) { 00569 return $out; 00570 } else { 00571 print $out; 00572 } 00573 } 00574 00575 function _check_for_leading_tabs( $string ) { 00576 return preg_match('/^\t/m', $string); 00577 } 00578 00579 function _remove_exessive_leading_tabs( $string ) { 00580 /* remove whitespace lines at start of the string */ 00581 $string = preg_replace('/^\s*\n/', '', $string); 00582 /* remove whitespace at end of the string */ 00583 $string = preg_replace('/\s*$/', '', $string); 00584 00585 # kleinste Anzahl von f�hrenden TABS z�hlen 00586 preg_match_all('/^\t+/', $string, $matches); 00587 $minTabCount = strlen(@min($matches[0])); 00588 00589 # und entfernen 00590 $string = preg_replace('/^\t{'.$minTabCount.'}/m', '', $string); 00591 00592 return $string; 00593 } 00594 00595 ?>