wangtengyu
2018-12-07 f459412e0dac4ed94106da043b4c6f8576bfe496
commit | author | age
19351a 1 <?php
B 2
3 /************************************************
4 ** Title.........: PHP4+ Debug Helper
5 ** Author........: Thomas Sch&#51180;er <code at atomar dot de>
6 ** Filename......: debuglib.php(s)
7 ** Last changed..: 12.07.2004 14:13
8 ** License.......: Free to use. Postcardware ;)
9 **
10 *************************************************
11 **
12 ** Functions in this library:
13 **
14 ** print_a( array array [,int returnmode] [,bool show object vars] [,int max entries] )
15 **
16 **   prints arrays in a readable form.
17 **   if mode is defined the function returns the output instead of printing it to the output buffer
18 **
19 **   print_a( $array, #, 1 ) shows also object properties
20 **   print_a( $array, 1, # ) returns the table as a string instead of printing it to the output buffer
21 **   print_a( $array, 'WindowName', #) opens the output in a window indentified by the string.
22 **   print_a( $array, '_WindowName', #) prints the array inside a frame (<fieldset><label>WindowName</label>...</fieldset>)
23 **   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 ;).
24 **
25 ** show_vars( [bool verbose] [, bool show_object_vars ] [, int limit] )
26 **
27 **   use this function on the bottom of your script to see all
28 **   superglobals and global variables in your script in a nice
29 **   formated way
30 **
31 **   show_vars() without parameter shows $_GET, $_POST, $_SESSION,
32 **   $_FILES and all global variables you've defined in your script
33 **
34 **   show_vars(1) shows $_SERVER and $_ENV in addition
35 **   show_vars(#,1) shows also object properties
36 **   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 )
37 **   show_vars(#, #, 0) shows all entries
38 **
39 **
40 **
41 ** ** print_result( result_handle ) **
42 **   prints a mysql_result set returned by mysql_query() as a table
43 **   this function is work in progress! use at your own risk
44 **
45 **
46 ** Happy debugging and feel free to email me your comments.
47 **
48 **
49 **
50 ** History: (starting at 2003-02-24)
51 **
52 **   - added tooltips to the td's showing the type of keys and values (thanks Itomic)
53 ** 2003-07-16
54 **   - pre() function now trims trailing tabulators
55 ** 2003-08-01
56 **   - silly version removed.. who needs a version for such a thing ;)
57 ** 2003-09-24
58 **   - changed the parameters of print_a() a bit
59 **     see above
60 **   - addet the types NULL and bolean to print_a()
61 **   - print_a() now replaces trailing spaces in string values with red underscores
62 ** 2003-09-24 (later that day ;)
63 **   - oops.. fixed the print_a() documentation.. parameter order was wrong
64 **   - added mode 3 to the second parameter
65 ** 2003-09-25
66 **   - added a limit parameter to the show_vars() and print_a() functions
67 **     default for show_vars() is 5
68 **     show_vars(#,#, n) changes that (0 means show all entries)
69 **     print_a() allways shows all entries by default
70 **     print_a(#,#,#, n) changes that
71 **
72 **     this parameter is used to limit the output of arrays with a numerical index (like long lists of similiar elements)
73 **     i added this option for performance reasons
74 **     it has no effect on arrays where one ore more keys are not number-strings
75 ** 2003-09-27
76 **   - reworked the pre() and _remove_exessive_leading_tabs() functions
77 **     they now work like they should :)
78 **   - some cosmetic changes
79 ** 2003-10-28
80 **   - fixed multiline string display
81 ** 2003-11-14
82 **   - argh! uploaded the wrong version :/ ... fixed.. sorry
83 ** 2003-11-16
84 **   - fixed a warning triggered by _only_numeric_keys()
85 **     thanx Peter Valdemar :)
86 **   - fixed a warning when print_a was called directly on an object
87 **     thanx Hilton :)
88 ** 2003-12-01
89 **   - added slashes in front of the print_a(#,3) output
90 ** 2004-03-17
91 **   - fixed a problem when print_a(#,2) was called on an array containing newlines
92 ** 2004-03-26
93 **   - added a variation of mode 2 for print_a().
94 **     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#
95 ** 2004-07-12
96 **   - print_a($array, '_MyLabel') draws a frame with a label around the output
97 ************************************************/
98
99 if (!defined('USE_DEBUGLIB')) define('USE_DEBUGLIB', true);
100
101 if (USE_DEBUGLIB) {
102
103     # This file must be the first include on your page.
104
105     /* used for tracking of generation-time */
106     {
107         $MICROTIME_START = microtime();
108         @$GLOBALS_initial_count = count($GLOBALS);
109     }
110
111     /************************************************
112     ** print_a class and helper function
113     ** prints out an array in a more readable way
114     ** than print_r()
115     **
116     ** based on the print_a() function from
117     ** Stephan Pirson (Saibot)
118     ************************************************/
119
120     class Print_a_class {
121
122         # this can be changed to true if you want
123         var $look_for_leading_tabs = false;
124
125         var $output;
126         var $iterations;
127         var $key_bg_color = '1E32C8';
128         var $value_bg_color = 'DDDDEE';
129         var $fontsize = '8pt';
130         var $keyalign = 'left';
131         var $fontfamily = 'Verdana';
132         var $show_object_vars;
133         var $limit;
134
135         // function Print_a_class() {}
136
137         # recursive function!
138
139         /* this internal function looks if the given array has only numeric values as  */
140         function _only_numeric_keys( $array ) {
141             $test = true;
142             if (is_array($array)) {
143                 foreach ( array_keys( $array ) as $key ) {
144                     if( !is_numeric( $key ) )   $test = false; /* #TODO# */
145                 }
146
147                 return $test;
148             } else {
149                 return false;
150             }
151         }
152
153         function _handle_whitespace( $string ) {
154             $string = str_replace(' ', '&nbsp;', $string);
155             $string = preg_replace(array('/&nbsp;$/', '/^&nbsp;/'), '<span style="color:red;">_</span>', $string); /* replace spaces at the start/end of the STRING with red underscores */
156             $string = preg_replace('/\t/', '&nbsp;&nbsp;<span style="border-bottom:#'.$this->value_bg_color.' solid 1px;">&nbsp;</span>', $string); /* replace tabulators with '_ _' */
157
158             return $string;
159         }
160
161         function print_a($array, $iteration = false, $key_bg_color = false) {
162             $key_bg_color or $key_bg_color = $this->key_bg_color;
163
164             # lighten up the background color for the key td's =)
165             if( $iteration ) {
166                 for ($i=0; $i<6; $i+=2) {
167                     $c = substr( $key_bg_color, $i, 2 );
168                     $c = hexdec( $c );
169                     ( $c += 15 ) > 255 and $c = 255;
170                     isset($tmp_key_bg_color) or $tmp_key_bg_color = '';
171                     $tmp_key_bg_color .= sprintf( "%02X", $c );
172                 }
173                 $key_bg_color = $tmp_key_bg_color;
174             }
175
176             # build a single table ... may be nested
177             $this->output .= '<table style="border:none;" cellspacing="1">';
178             $only_numeric_keys = ($this->_only_numeric_keys( $array ) || count( $array ) > 50);
179             $i = 0;
180             foreach ($array as $key => $value)
181             {
182                 if( $only_numeric_keys && $this->limit && $this->limit == $i++ ) break; /* if print_a() was called with a fourth parameter #TODO# */
183
184                 $value_style_box = 'color:black;';
185                 $key_style = 'color:white;';
186
187                 $type = gettype( $value );
188                 # print $type.'<br />';
189
190                 # change the color and format of the value and set the values title
191                 $type_title = $type;
192                 $value_style_content = '';
193                 switch( $type ) {
194                     case 'array':
195                         if( empty( $value ) ) $type_title = 'empty array';
196                         break;
197
198                     case 'object':
199                         $key_style = 'color:#FF9B2F;';
200                         break;
201
202                     case 'integer':
203                         $value_style_box = 'color:green;';
204                         break;
205
206                     case 'double':
207                         $value_style_box = 'color:blue;';
208                         break;
209
210                     case 'boolean':
211                         if( $value == true ) {
212                             $value_style_box = 'color:#D90081;';
213                         } else {
214                             $value_style_box = 'color:#84009F;';
215                         }
216                         break;
217
218                     case 'NULL':
219                         $value_style_box = 'color:darkorange;';
220                         break;
221
222                     case 'string':
223                         if( $value == '' ) {
224
225                             $value_style_box = 'color:darkorange;';
226                             $value = "''";
227                             $type_title = 'empty string';
228
229                         } else {
230
231                             $value_style_box = 'color:black;';
232                             $value = htmlspecialchars( $value );
233                             if( $this->look_for_leading_tabs && _check_for_leading_tabs( $value ) ) {
234                                 $value = _remove_exessive_leading_tabs( $value );
235                             }
236                             $value = $this->_handle_whitespace( $value );
237                             $value = nl2br($value);
238
239                             /* use different color for string background */
240                             if(strstr($value, "\n")) $value_style_content = 'background:#ECEDFE;';
241
242                         }
243                         break;
244                 }
245
246                 $this->output .= '<tr>';
247                 $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.']">';
248                 $this->output .= $this->_handle_whitespace( $key );
249                 $this->output .= '</td>';
250                 $this->output .= '<td nowrap="nowrap" style="background-color:#'.$this->value_bg_color.';font: '.$this->fontsize.' '.$this->fontfamily.'; color:black;">';
251
252                 # value output
253                 if($type == 'array' && preg_match('/#RAS/', $key) ) { /* only used for special recursive array constructs which i use sometimes */
254                     $this->output .= '<div style="'.$value_style_box.'">recursion!</div>';
255                 } elseif($type == 'array') {
256                     if( ! empty( $value ) ) {
257                         $this->print_a( $value, true, $key_bg_color );
258                     } else {
259                         $this->output .= '<span style="color:darkorange;">[]</span>';
260                     }
261                 } elseif($type == 'object') {
262                     if( $this->show_object_vars ) {
263                         $objects_class = get_class($value);
264                         $this->print_a( array('CLASS_NAME' => $objects_class), true, '204FB8' );
265                         $this->print_a( array('CLASS_VARS' => get_class_vars( $objects_class )), true, '2066B8' );
266                         $this->print_a( array('CLASS_METHODS' => get_class_methods( $objects_class )), true, '2067EB8' );
267                         $this->print_a( array('OBJECT_VARS' => get_object_vars( $value )), true, '2095B8' );
268                     } else {
269                         $this->output .= '<div style="'.$value_style_box.'">OBJECT</div>';
270                     }
271                 } elseif($type == 'boolean') {
272                     $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'">'.($value ? 'true' : 'false').'</div>';
273                 } elseif($type == 'NULL') {
274                     $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'">NULL</div>';
275                 } else {
276                     $this->output .= '<div style="'.$value_style_box.'" title="'.$type.'"><span style="'.$value_style_content.'">'.$value.'</span></div>';
277                 }
278
279                 $this->output .= '</td>';
280                 $this->output .= '</tr>';
281             }
282
283             $entry_count = count( $array );
284             $skipped_count = $entry_count - $this->limit;
285
286             if( $only_numeric_keys && $this->limit && count($array) > $this->limit) {
287                 $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>';
288             }
289             $this->output .= '</table>';
290         }
291     }
292
293     # helper function.. calls print_a() inside the print_a_class
294     function print_a( $array, $mode = 0, $show_object_vars = false, $limit = false ) {
295         $output = '';
296
297         if( is_array( $array ) or is_object( $array ) ) {
298
299             if( empty( $array ) ) {
300                 $output .= '<span style="color:red;font-size:small;">print_a( empty array )</span>';
301             }
302
303             $pa = new Print_a_class;   //´úÂëÐ޸Ġ By  
304             $show_object_vars and $pa->show_object_vars = true;
305             if( $limit ) {
306                 $pa->limit = $limit;
307                 // $output .= '<span style="color:red;">showing only '.$limit.' entries for arrays with numeric keys</span>';
308             }
309
310             if ( is_object($array) ) {
311
312               $pa->print_a( get_object_vars($array) );
313
314             } else {
315
316               $pa->print_a( $array );
317             }
318
319             # $output = $pa->output; unset($pa);
320             $output .= $pa->output;
321         } elseif( gettype($array) == 'boolean') {
322             $output .= '<span style="color:red;font-size:small;">print_a( '.($array === true ? 'true' : 'false').' )</span>';
323         } else {
324             $output .= '<span style="color:red;font-size:small;">print_a( '.gettype( $array ).' )</span>';
325         }
326
327         if($mode === 0 || $mode == NULL || $mode == false) {
328             print $output;
329             return true;
330         }
331
332         if($mode == 1) {
333             return $output;
334         }
335
336         if(is_string($mode) || $mode == 2 ) {
337             $debugwindow_origin = $_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
338
339             if(preg_match('/(.+)::(.+)/', $mode, $matches)) {
340                 $mode = $matches[1];
341                 $remote_addr = gethostbyname($matches[2]);
342                 if($_SERVER['REMOTE_ADDR'] != $remote_addr) return;
343             }
344
345             if(preg_match('/^_(.*)/', $mode, $matches)) {
346                 #$output = "<table style=\"border:1px solid black;\" cellpadding=\"0\" cellspcing=\"0\"><tr><td style=\"background:#1E2B9E;color:white;font-weight:bold;padding:2px;\">{$matches[1]}</td></tr><tr><td>$output</td></tr></table>";
347                 $output = "<fieldset style=\"width:100px;padding:2px;border:1px solid #666666;\"><legend>{$matches[1]}</legend>$output</fieldset><br />";
348
349                 print $output;
350             } else {
351
352                         print '
353                 <script type="text/javascript" language="JavaScript">
354                 var debugwindow;
355                 debugwindow = window.open("", "T_'.md5($_SERVER['HTTP_HOST']).(is_string($mode)  ? $mode : '').'", "menubar=no,scrollbars=yes,resizable=yes,width=640,height=480");
356                 debugwindow.document.open();
357                 debugwindow.document.write("'.str_replace(array("\r\n", "\n", "\r"), '\n', addslashes($output)).'");
358                 debugwindow.document.close();
359                 debugwindow.document.title = "'.(is_string($mode) ? "($mode)" : '').' Debugwindow for : http://'.$debugwindow_origin.'";
360                 debugwindow.focus();
361                 </script>
362                 ';
363             }
364         }
365
366         if($mode == 3) {
367             print '
368                 <script type="text/javascript" language="JavaScript">
369                     var debugwindow;
370                     debugwindow = window.open("", "S_'.md5($_SERVER['HTTP_HOST']).'", "menubar=yes,scrollbars=yes,resizable=yes,width=640,height=480");
371                     debugwindow.document.open();
372                     debugwindow.document.write("unserialize(\''.str_replace("'", "\\'", addslashes( str_replace(array("\r\n", "\n", "\r"), '\n', serialize($array) ) ) ).'\');");
373                     debugwindow.document.close();
374                     debugwindow.document.title = "Debugwindow for : http://'.$debugwindow_origin.'";
375                     debugwindow.focus();
376                 </script>
377             ';
378         }
379
380     }
381
382     // shows mysql-result as a table.. # not ready yet :(
383     function print_result($RESULT) {
384
385         if(!$RESULT) return;
386
387         if(mysql_num_rows($RESULT) < 1) return;
388         $fieldcount = mysql_num_fields($RESULT);
389
390         for ($i=0; $i<$fieldcount; $i++) {
391             $tables[mysql_field_table($RESULT, $i)]++;
392         }
393
394         print '
395             <style type="text/css">
396                 .rs_tb_th {
397                     font-family: Verdana;
398                     font-size:9pt;
399                     font-weight:bold;
400                     color:white;
401                 }
402                 .rs_f_th {
403                     font-family:Verdana;
404                     font-size:7pt;
405                     font-weight:bold;
406                     color:white;
407                 }
408                 .rs_td {
409                     font-family:Verdana;
410                     font-size:7pt;
411                 }
412             </style>
413             <script type="text/javascript" language="JavaScript">
414                 var lastID;
415                 function highlight(id) {
416                     if(lastID) {
417                         lastID.style.color = "#000000";
418                         lastID.style.textDecoration = "none";
419                     }
420                     tdToHighlight = document.getElementById(id);
421                     tdToHighlight.style.color ="#FF0000";
422                     tdToHighlight.style.textDecoration = "underline";
423                     lastID = tdToHighlight;
424                 }
425             </script>
426         ';
427
428         print '<table bgcolor="#000000" cellspacing="1" cellpadding="1">';
429
430         print '<tr>';
431         foreach ($tables as $tableName => $tableCount) {
432             $col == '0054A6' ? $col = '003471' : $col = '0054A6';
433             print '<th colspan="'.$tableCount.'" class="rs_tb_th" style="background-color:#'.$col.';">'.$tableName.'</th>';
434         }
435         print '</tr>';
436
437         print '<tr>';
438         for ($i=0;$i < mysql_num_fields($RESULT);$i++) {
439             $FIELD = mysql_field_name($RESULT, $i);
440             $col == '0054A6' ? $col = '003471' : $col = '0054A6';
441             print '<td align="center" bgcolor="#'.$col.'" class="rs_f_th">'.$FIELD.'</td>';
442         }
443         print '</tr>';
444
445         mysql_data_seek($RESULT, 0);
446
447         while ($DB_ROW = mysql_fetch_array($RESULT, MYSQL_NUM)) {
448             $pointer++;
449             if($toggle) {
450                 $col1 = "E6E6E6";
451                 $col2 = "DADADA";
452             } else {
453                 $col1 = "E1F0FF";
454                 $col2 = "DAE8F7";
455             }
456             $toggle = !$toggle;
457             print '<tr id="ROW'.$pointer.'" onMouseDown="highlight(\'ROW'.$pointer.'\');">';
458             foreach ($DB_ROW as $value) {
459                 $col == $col1 ? $col = $col2 : $col = $col1;
460                 print '<td valign="top" bgcolor="#'.$col.'" class="rs_td" nowrap>'.nl2br($value).'</td>';
461             }
462             print '</tr>';
463         }
464         print '</table>';
465         mysql_data_seek($RESULT, 0);
466     }
467
468     ######################
469     # reset the millisec timer
470     #
471     function reset_script_runtime() {
472         $GLOBALS['MICROTIME_START'] = microtime();
473     }
474
475     ######################
476     # function returns the milliseconds passed
477     #
478     function script_runtime() {
479         $MICROTIME_END      = microtime();
480         $MICROTIME_START    = explode(' ', $GLOBALS['MICROTIME_START']);
481         $MICROTIME_END      = explode(' ', $MICROTIME_END);
482         $GENERATIONSEC      = $MICROTIME_END[1] - $MICROTIME_START[1];
483         $GENERATIONMSEC = $MICROTIME_END[0] - $MICROTIME_START[0];
484         $GENERATIONTIME = substr($GENERATIONSEC + $GENERATIONMSEC, 0, 8);
485
486         return (float) $GENERATIONTIME;
487     }
488
489     function _script_globals() {
490         global $GLOBALS_initial_count;
491
492         $varcount = 0;
493
494         foreach ($GLOBALS as $GLOBALS_current_key => $GLOBALS_current_value) {
495             if(++$varcount > $GLOBALS_initial_count) {
496                 /* die wollen wir nicht! */
497                 if ($GLOBALS_current_key != 'HTTP_SESSION_VARS' && $GLOBALS_current_key != '_SESSION') {
498                     $script_GLOBALS[$GLOBALS_current_key] = $GLOBALS_current_value;
499                 }
500             }
501         }
502
503         unset($script_GLOBALS['GLOBALS_initial_count']);
504         return $script_GLOBALS;
505     }
506
507     ######################
508     # function shows all superglobals and script defined global variables
509     # show_vars() without the first parameter shows all superglobals except $_ENV and $_SERVER
510     # show_vars(1) shows all
511     # show_vars(#,1) shows object properties in addition
512     #
513     function show_vars($show_all_vars = false, $show_object_vars = false, $limit = 5) {
514         if($limit === 0) $limit = false;
515
516         if(isset($GLOBALS['no_vars'])) return;
517
518         $script_globals = _script_globals();
519         print '
520             <style type="text/css" media="screen">
521                 .vars-container {
522                     font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif;
523                     font-size: 8pt;
524                     padding:5px;
525                 }
526                 .varsname {
527                     font-weight:bold;
528                 }
529                 .showvars {
530                     background:white;
531                     border-style:dotted;
532                     border-width:1px;
533                     padding:2px;
534                     font-family: Verdana, Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif;
535                     font-size:10pt;
536                     font-weight:bold;"
537                 }
538             </style>
539             <style type="text/css" media="print">
540                 .showvars {
541                     display:none;
542                     visibility:invisible;
543                 }
544             </style>
545         ';
546
547         print '<br />
548             <div class="showvars">
549             DEBUG <span style="color:red;font-weight:normal;font-size:9px;">(runtime: '.script_runtime().' sec)</span>
550         ';
551
552         $vars_arr['script_globals'] = array('global script variables', '#7ACCC8');
553         $vars_arr['_GET'] = array('$_GET', '#7DA7D9');
554         $vars_arr['_POST'] = array('$_POST', '#F49AC1');
555         $vars_arr['_FILES'] = array('$_FILES', '#82CA9C');
556         $vars_arr['_SESSION'] = array('$_SESSION', '#FCDB26');
557         $vars_arr['_COOKIE'] = array('$_COOKIE', '#A67C52');
558
559         if($show_all_vars) {
560             $vars_arr['_SERVER'] =  array('SERVER', '#A186BE');
561             $vars_arr['_ENV'] =  array('ENV', '#7ACCC8');
562         }
563
564         foreach ($vars_arr as $vars_name => $vars_data) {
565             if($vars_name != 'script_globals') global $$vars_name;
566             if($$vars_name) {
567                 print '<div class="vars-container" style="background-color:'.$vars_data[1].';"><span class="varsname">'.$vars_data[0].'</span><br />';
568                 print_a($$vars_name, NULL, $show_object_vars, $limit);
569                 print '</div>';
570             }
571         }
572         print '</div>';
573     }
574
575     ######################
576     # function prints/returns strings wrapped between <pre></pre>
577     #
578     function pre( $string, $return_mode = false, $tabwidth = 3 ) {
579         $tab = str_repeat('&nbsp;', $tabwidth);
580         $string = preg_replace('/\t+/em', "str_repeat( ' ', strlen('\\0') * $tabwidth );", $string); /* replace all tabs with spaces */
581
582         $out = '<pre>'.$string."</pre>\n";
583
584         if($return_mode) {
585             return $out;
586         } else {
587             print $out;
588         }
589     }
590
591     function _check_for_leading_tabs( $string ) {
592         return preg_match('/^\t/m', $string);
593     }
594
595     function _remove_exessive_leading_tabs( $string ) {
596         /* remove whitespace lines at start of the string */
597         $string = preg_replace('/^\s*\n/', '', $string);
598         /* remove whitespace at end of the string */
599         $string = preg_replace('/\s*$/', '', $string);
600
601         # kleinste Anzahl von f&#51762;enden TABS z&#18988;en
602         preg_match_all('/^\t+/', $string, $matches);
603         $minTabCount = strlen(@min($matches[0]));
604
605         # und entfernen
606         $string = preg_replace('/^\t{'.$minTabCount.'}/m', '', $string);
607
608         return $string;
609     }
610 } // use debuglib
611
612 // Define no-op functions in case debug functions were accidentally left
613 // in the live system.
614 else {
615     function print_a() {}
616     function print_result() {}
617     function reset_script_runtime() {}
618     function script_runtime() {}
619     function show_vars() {}
620     function pre() {}
621 } // don't use debuglib
622
623 ?>