Source for file debugger.php

Documentation is available at debugger.php

  1. <?php
  2. /* ******************************************************************** */
  3. /* CATALYST PHP Source Code */
  4. /* -------------------------------------------------------------------- */
  5. /* This program is free software; you can redistribute it and/or modify */
  6. /* it under the terms of the GNU General Public License as published by */
  7. /* the Free Software Foundation; either version 2 of the License, or */
  8. /* (at your option) any later version. */
  9. /* */
  10. /* This program is distributed in the hope that it will be useful, */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  13. /* GNU General Public License for more details. */
  14. /* */
  15. /* You should have received a copy of the GNU General Public License */
  16. /* along with this program; if not, write to: */
  17. /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
  18. /* Boston, MA 02111-1307 USA */
  19. /* -------------------------------------------------------------------- */
  20. /* */
  21. /* Filename: debugger.php */
  22. /* Author: Paul Waite */
  23. /* Description: Definitions for the debugger module. */
  24. /* */
  25. /* ******************************************************************** */
  26. /** @package core */// some control over what messages appear on output..
  27.  
  28. /** Dummy value */
  29. ("DBG_UNDEFINED", -1);
  30. /** No debugging (redundant) */
  31. ("DBG_NONE", 0);
  32. /** Ad-hoc debugging output */
  33. ("DBG_DEBUG", 1);
  34. /** Diagnostic output */
  35. ("DBG_DIAGNOSTIC", 2);
  36. /** SQL queries to database */
  37. ("DBG_SQL", 4);
  38. /** SQL SELECT data from database */
  39. ("DBG_SQLDATA", 8);
  40. /** Dump HTTP and PHP page vars */
  41. ("DBG_DUMP", 16);
  42. /** Provide debug traceback info */
  43. ("DBG_TRACE", 32);
  44. /** Show table borders and validation checks */
  45. ("DBG_TABLES", 64);
  46. /** Show debugging profiler output */
  47. ("DBG_PROFILE", 128);
  48. /** Show site authentication output */
  49. ("DBG_AUTH", 256);
  50. /** DEBUG and DIAGNOSTICS as default setting */
  51. ("DBG_DEFAULT", 3);
  52. /** Everything. Warning, this can be VERBOSE! */
  53. ("DBG_ALL", 511);
  54.  
  55. // Defined output options. Where debug output goes..
  56. /** No output */
  57. ("DBG_O_NONE", 0);
  58. /** Output stored in $content */
  59. ("DBG_O_STORED", 1);
  60. /** Output via direct echo */
  61. ("DBG_O_ECHO", 2);
  62. /** Output for CLI: echoed raw ASCII, LF end-of-line */
  63. ("DBG_O_CLI", 4);
  64. /** Output to system log */
  65. ("DBG_O_LOG", 8);
  66. /** To logfile (not implemented yet) */
  67. ("DBG_O_LOGFILE", 16);
  68. /** Default output mode (stored) */
  69. ("DBG_O_DEFAULT", 1);
  70. /** Ubiquitous output mode */
  71. ("DBG_O_ALL", 255);
  72.  
  73. //-----------------------------------------------------------------------
  74. /**
  75. * The debugger class. Responsible for accumulating, filtering and then
  76. * rendering debug content to various outputs. This class is automatically
  77. * instantiated by the system as $RESPONSE->debugger; and is used by various
  78. * modules (eg. query) to log information. It can also be used as either
  79. * an ad-hoc debugging aid, or as an analysis tool where debug output
  80. * statements are inserted into code and left there permanently, their output
  81. * only switched on when problems arise. Various classes of debug output can
  82. * be enabled in any combination by OR'ing the following constants when the
  83. * debug_on() function is called:
  84. * DBG_DEBUG Ad-hoc debugging output
  85. * DBG_DIAGNOSTIC Diagnostic output
  86. * DBG_SQL SQL queries to database
  87. * DBG_SQLDATA SQL SELECT data from database
  88. * DBG_DUMP Dump HTTP and PHP page vars
  89. * DBG_TRACE Provide debug traceback info
  90. * DBG_TABLES Show table borders and validate cells
  91. * DBG_PROFILES Show process profiling information
  92. * DBG_AUTH Authentication messages
  93. * DBG_DEFAULT DEBUG and DIAGNOSTICS only
  94. * DBG_ALL Everything (verbose!)
  95. * eg. debug_on(DBG_SQL | DBG_DIAGNOSTIC | DBG_DUMP);
  96. * @package core
  97. */
  98. class webdebugger extends RenderableObject {
  99. // Public
  100. /** Accumulated debugging output content */
  101.  
  102. var $content = "";
  103. /** Classes of debugging to accumulate */
  104.  
  105. var $debugclass = DBG_DEFAULT;
  106. /** Status of the debugger */
  107.  
  108. var $enabled = false;
  109. /** Modes of output for debugging content */
  110.  
  111. var $output_mode = DBG_O_DEFAULT;
  112.  
  113. // Private
  114. /** Array of traced locations
  115. @access private */
  116. var $trace = array();
  117. /** Depth of tracing
  118. @access private */
  119. var $tracedepth = 0;
  120. /** Microtimer object for profiling
  121. @access private */
  122. var $profile_timer;
  123. /** Profiler data array
  124. @access private */
  125. var $profile = array();
  126.  
  127. // ................................................................
  128. /**
  129. * Constructor
  130. * @param integer $debugclass The classes of output to render
  131. */
  132. function webdebugger($debugclass=DBG_DEFAULT) {
  133. $this->debug_class($debugclass);
  134. }
  135. // ................................................................
  136. /**
  137. * Return whether we have any content, true or false.
  138. */
  139. function debug_hascontent() {
  140. return (
  141. $this->enabled &&
  142. (
  143. (strlen($this->content) > 0)
  144. || ($this->debugclass & DBG_DUMP)
  145. || ($this->profiling() && count($this->profile) > 0)
  146. )
  147. );
  148. }
  149. // ................................................................
  150. /**
  151. * Set debug output mode
  152. * This function starts/stops the debugger from echoing
  153. * the content directly as well as storing it for a
  154. * subsequent display by webpage-defs.php. The values which
  155. * can be OR'ed together are as follows:
  156. * DBG_O_NONE No output
  157. * DBG_O_STORED Output stored in $content
  158. * DBG_O_ECHO Output via direct echo
  159. * DBG_O_CLI Output for CLI: echoed tag-stripped ASCII, LF end-of-line
  160. * DBG_O_LOG Output to system log
  161. * DBG_O_LOGFILE To logfile (not implemented yet)
  162. * DBG_O_DEFAULT Default output mode (echoed)
  163. * DBG_O_ALL Ubiquitous output mode
  164. * @param integer $mode Output mode of debugger
  165. */
  166. function debug_output($mode=DBG_O_DEFAULT) {
  167. $this->output_mode = $mode;
  168. }
  169. // ................................................................
  170. /**
  171. * Set debug output mode
  172. * Register content for debugging output. Check that it is
  173. * of an acceptable class and direct it all to the right place(s).
  174. * @param string $content Content to add to debug output buffer
  175. * @param integer $debugclass Class of output
  176. */
  177. function debug_write($content, $debugclass=DBG_DIAGNOSTIC) {
  178. if ($this->enabled) {
  179. // Are we providing traceback info..
  180. if ($this->debugclass & DBG_TRACE) {
  181. if ($this->tracedepth > 0) {
  182. $content .= "[ " . $this->traceback() . " ] ";
  183. }
  184. }
  185. // Direct debugging content where we should..
  186. if ($debugclass & $this->debugclass) {
  187. if ($this->output_mode & DBG_O_STORED) {
  188. $this->content .= $content;
  189. }
  190. if ($this->output_mode & DBG_O_ECHO) {
  191. echo $content;
  192. }
  193. if ($this->output_mode & DBG_O_CLI) {
  194. $s = str_replace("<br>", "\n", html_entity_decode($content));
  195. if (!strstr($content, "<pre>")) {
  196. $s = strip_tags($s);
  197. }
  198. echo $s;
  199. }
  200. if ($this->output_mode & DBG_O_LOG) {
  201. error_log(strip_tags(html_entity_decode($content)), 0);
  202. }
  203. }
  204. }
  205. return $this;
  206. }
  207. // ................................................................
  208. /**
  209. * Set debug class(es) to accept
  210. * @param integer $debugclass Class of output
  211. */
  212. function debug_class($debugclass) {
  213. if (isset($debugclass)) {
  214. $this->debugclass = $debugclass & DBG_ALL;
  215. if ($this->debugclass == DBG_NONE)
  216. $this->enabled = false;
  217. }
  218. return $this;
  219. }
  220. // ................................................................
  221. /**
  222. * Set debug mode
  223. * Set debug output to be enabled(default)/disabled
  224. * @param boolean $enabled If true enable debugger, else disable it
  225. * @param integer $debugclass Class of output to accept
  226. */
  227. function debug_mode($enabled=true, $debugclass=DBG_UNDEFINED) {
  228. $this->enabled = $enabled;
  229. if ($enabled) {
  230. $this->debug_class($debugclass);
  231. }
  232. return $this;
  233. }
  234. // ................................................................
  235. /**
  236. * Flag debugger to dump global variables
  237. * Sets a flag for the debugger to dump all global vars at output time.
  238. * @access private
  239. */
  240. function debug_dump() {
  241. $this->debugclass |= DBG_DUMP;
  242. return $this;
  243. }
  244. // ................................................................
  245. /**
  246. * Profile breakpoint.
  247. * Profiling allows you to ascertain the elapsed time between two
  248. * breakpoints. To do this just call this method twice with the same
  249. * label.
  250. * @param string $label A label for this profile breakpoint
  251. */
  252. function profile($label) {
  253. if (!isset($this->profile_timer)) {
  254. $this->profile_timer = new microtimer();
  255. $this->profile_timer->start();
  256. }
  257. $ms = $this->profile_timer->millisecs();
  258. if (isset($this->profile[$label])) {
  259. $bits = explode("|", $this->profile[$label]);
  260. $elapsed = $bits[0];
  261. $started = $bits[1];
  262. $finished = $bits[2];
  263. $calls = $bits[3];
  264. // Ending a profiling section
  265. if ($finished == "") {
  266. $finished = $ms;
  267. $elapsed += ($finished - $started);
  268. $calls += 1;
  269. }
  270. // Starting a profiling section..
  271. else {
  272. $started = $ms;
  273. $finished = "";
  274. }
  275. }
  276. else {
  277. $elapsed = 0;
  278. $started = $ms;
  279. $finished = "";
  280. $calls = 0;
  281. }
  282. $this->profile[$label] = "$elapsed|$started|$finished|$calls";
  283. }
  284. // ................................................................
  285. /** This makes sure the profiles are all finished.
  286. * @access private
  287. */
  288. function profile_close() {
  289. if (isset($this->profile_timer)) {
  290. $this->profile_timer->stop();
  291. foreach ($this->profile as $label => $prof) {
  292. $bits = explode("|", $prof);
  293. if ($bits[2] == "") {
  294. $this->profile($label);
  295. }
  296. }
  297. }
  298. }
  299. // ................................................................
  300. /** Returns true if this debugger is in profiling mode. */
  301.  
  302. function profiling() {
  303. return $this->debugclass & DBG_PROFILE;
  304. }
  305. // ................................................................
  306. /**
  307. * List classes debugger is accepting
  308. * @return string List of classes acceptable to the debugger
  309. */
  310. function report_classes() {
  311. $rpt = array();
  312. if ($this->debugclass & DBG_TRACE) $rpt[] = "TRACEBACK";
  313. if ($this->debugclass & DBG_SQL) $rpt[] = "SQL";
  314. if ($this->debugclass & DBG_DEBUG) $rpt[] = "DEBUG";
  315. if ($this->debugclass & DBG_DIAGNOSTIC) $rpt[] = "DIAGNOSTIC";
  316. if ($this->debugclass & DBG_DUMP) $rpt[] = "DUMP";
  317. if ($this->debugclass & DBG_TABLES) $rpt[] = "TABLES";
  318. if ($this->debugclass & DBG_PROFILE) $rpt[] = "PROFILER";
  319. if ($this->debugclass & DBG_AUTH) $rpt[] = "AUTH";
  320. return implode(",", $rpt);
  321. }
  322. // ................................................................
  323. /**
  324. * Push a trace on stack
  325. * Pushes a traceback label onto our trace stack. We return the
  326. * depth of trace we are at.
  327. * @param mixed $traceobj Thing to push on the stack
  328. * @return integer Depth of tracing so far
  329. * @access private
  330. */
  331. function pushtrace($traceobj) {
  332. if ($this->debugclass & DBG_TRACE) {
  333. // First determine the trace label..
  334. if (is_object($traceobj)) {
  335. $label = "<font color=blue>" . get_class($traceobj) . "</font>";
  336. }
  337. elseif (is_string($traceobj)) {
  338. $label = "<font color=green>" . $traceobj . "</font>";
  339. }
  340. else {
  341. $label = "unknown";
  342. }
  343. array_push($this->trace, $label);
  344. $this->tracedepth = count($this->trace);
  345. // Automatic trace profiling..
  346. if ($this->profiling()) {
  347. $this->profile(strip_tags($label));
  348. }
  349. }
  350. return $this->tracedepth;
  351. }
  352. // ................................................................
  353. /**
  354. * Pop a trace off stack
  355. * Pop a trace label off our trace stack
  356. * @access private
  357. */
  358. function poptrace() {
  359. if ($this->debugclass & DBG_TRACE) {
  360. if ($this->tracedepth > 0) {
  361. $label = array_pop($this->trace);
  362. if ($this->profiling()) {
  363. $this->profile(strip_tags($label));
  364. }
  365. return $label;
  366. }
  367. else {
  368. return "";
  369. }
  370. $this->tracedepth = count($this->trace);
  371. }
  372. }
  373. // ................................................................
  374. /**
  375. * Traceback list
  376. * Return a string of the form "label->label->label"
  377. * forming the traceback level labels in order.
  378. * @return string Traceback list
  379. */
  380. function traceback() {
  381. $traceback = "";
  382. if ($this->tracedepth > 0) {
  383. $ditto = "";
  384. foreach ($this->trace as $tracelabel) {
  385. if ($tracelabel != $ditto) {
  386. if ($traceback != "") $traceback .= "->";
  387. $traceback .= $tracelabel;
  388. $ditto = $tracelabel;
  389. }
  390. }
  391. }
  392. return $traceback;
  393. }
  394. // ................................................................
  395. /**
  396. * Use render() to render the debugger output.
  397. * Renders the debugger output content as HTML.
  398. * @see render()
  399. * @return string HTML rendering of debug output content
  400. */
  401. function html() {
  402. if (!$this->debug_hascontent()) return "";
  403.  
  404. // Get names of globals we will use. These depend on the
  405. // version of Php, since we won't rely on the old ones
  406. // sticking around forever..
  407. $vname_get = "HTTP_GET_VARS";
  408. $vname_post = "HTTP_POST_VARS";
  409. $vname_cookie = "HTTP_COOKIE_VARS";
  410. $vbits = explode(".", phpversion());
  411. $v1 = $vbits[0]; $v2 = $vbits[1];
  412. if (($v1 > 4) || ($v1 == 4 && $v2 >= 1)) {
  413. $vname_get = "_GET";
  414. $vname_post = "_POST";
  415. $vname_cookie = "_COOKIE";
  416. }
  417. // Bring them in..
  418. global $$vname_cookie;
  419. global $$vname_get;
  420. global $$vname_post;
  421. global $PHP_SELF;
  422. global $GLOBALS;
  423.  
  424. // Header stuff.,
  425. $header = "<h4>PHP Web Page Debugger</h4>";
  426. $header .= "<p>";
  427. $header .= "<b>File: $PHP_SELF</b><br>";
  428. $header .= "<b>Debug filter: " . $this->report_classes() . "</b><br>";
  429. $header .= "</p>";
  430. $footer = "+++ END OF DEBUG OUTPUT +++<br>";
  431. if ($this->debugclass & DBG_DUMP) {
  432. $s ="<p>";
  433. $s .= "<table border=1 cellpadding=2 cellspacing=0>";
  434. if (isset($$vname_cookie)) {
  435. $s .= "<tr><td colspan=2><h4>Cookie Vars</h4></td></tr>";
  436. reset($$vname_cookie);
  437. while (list($key, $val) = each($$vname_cookie)) {
  438. $s .= "<tr><td>$key</td><td>" . displayvar($val) . "</td></tr>";
  439. }
  440. }
  441. if (isset($$vname_get)) {
  442. $s .= "<tr><td colspan=2><h4>GET Vars</h4></td></tr>";
  443. reset($$vname_get);
  444. while (list($key, $val) = each($$vname_get)) {
  445. $s .= "<tr><td>$key</td><td>" . displayvar($val) . "</td></tr>";
  446. }
  447. }
  448. if (isset($$vname_post)) {
  449. $s .= "<tr><td colspan=2><h4>POSTed Vars</h4></td></tr>";
  450. reset($$vname_post);
  451. while (list($key, $val) = each($$vname_post)) {
  452. $s .= "<tr><td>$key</td><td>" . displayvar($val) . "</td></tr>";
  453. }
  454. }
  455. if (isset($GLOBALS)) {
  456. $s .= "<tr><td colspan=2><h4>Globals</h4></td></tr>";
  457. reset($GLOBALS);
  458. while (list($key, $val) = each($GLOBALS)) {
  459. $s .= "<tr><td>$key</td><td>" . displayvar($val) . "</td></tr>";
  460. }
  461. }
  462. $s .= "</table>";
  463. $s .= "</p>";
  464. $this->content .= $s;
  465. }
  466. // Profiler output..
  467. if ($this->profiling()) {
  468. $s ="<p>";
  469. $s .= "<table border=1 cellpadding=2 cellspacing=0>\n";
  470. $s .= "<tr><td colspan=6><h4>Profiler</h4></td></tr>\n";
  471. $s .= "<tr>";
  472. $s .= "<td>Label</td>";
  473. $s .= "<td align=center>Calls</td>";
  474. $s .= "<td align=center>mS/Call</td>";
  475. $s .= "<td align=center>mS</td>";
  476. $s .= "<td align=right>Rel%</td>";
  477. $s .= "<td>&nbsp</td>";
  478. $s .= "</tr>\n";
  479.  
  480. // Make sure all profiles are finished..
  481. $this->profile_close();
  482.  
  483. // Find max value first..
  484. $maxms = 0;
  485. $profiles = array();
  486. $calls = array();
  487. foreach ($this->profile as $label => $prof) {
  488. $bits = explode("|", $prof);
  489. if (isset($bits[0])) {
  490. $ms = (float) $bits[0];
  491. $profiles[$label] = $ms;
  492. if ($ms > $maxms) $maxms = $ms;
  493. $calls[$label] = $bits[3];
  494. }
  495. }
  496. $maxwidth = 50;
  497. if ($maxms > 0) {
  498. $scalefactor = $maxwidth / $maxms;
  499. }
  500. else {
  501. $scalefactor = 1;
  502. }
  503. //arsort($profiles);
  504. foreach ($profiles as $label => $ms) {
  505. $calltot = $calls[$label];
  506. $mspercall = number_format($ms/$calltot, 1);
  507. $width = (int) ceil($scalefactor * $ms);
  508. $pct = number_format(($ms / $maxms) * 100, 1);
  509. $bar = str_repeat("*", $width);
  510. $ms = number_format($ms, 2);
  511. $s .= "<tr>";
  512. $s .= "<td>$label</td>";
  513. $s .= "<td align=right>$calltot</td>";
  514. $s .= "<td align=right>$mspercall</td>";
  515. $s .= "<td align=right>$ms</td>";
  516. $s .= "<td align=right>$pct</td>";
  517. $s .= "<td valign=middle>$bar</td>";
  518. $s .= "</tr>\n";
  519. }
  520. $s .= "</table>\n";
  521. $s .= "</p>";
  522. $this->content .= $s;
  523. }
  524. return $header . $this->content . $footer;
  525. }
  526. // ................................................................
  527. /**
  528. * Use render() to render the debugger output.
  529. * Renders the debugger output content as WML.
  530. * @see render()
  531. * @return string WML rendering of debug output content
  532. */
  533. function wml() {
  534. if (!$this->debug_hascontent()) return "";
  535.  
  536. // Get names of globals we will use. These depend on the
  537. // version of Php, since we won't rely on the old ones
  538. // sticking around forever..
  539. if (version_compare(phpversion(), "4.1.0", "ge")) {
  540. $vname_get = "_GET";
  541. $vname_post = "_POST";
  542. }
  543. else {
  544. $vname_get = "HTTP_GET_VARS";
  545. $vname_post = "HTTP_POST_VARS";
  546. }
  547. global $$vname_get;
  548. global $$vname_post;
  549. global $GLOBALS;
  550. $s = "";
  551. if ($this->debugclass & DBG_DUMP) {
  552. $s .= "<b>Variables</b><br/>";
  553. if (isset($$vname_get)) {
  554. $s .= "GET Vars:<br/>";
  555. reset($$vname_get);
  556. while (list($key, $val) = each($$vname_get)) {
  557. $s .= "$key=" . displayvar($val) . "<br/>";
  558. }
  559. }
  560. if (isset($$vname_post)) {
  561. $s .= "POSTed Vars:<br/>";
  562. reset($$vname_post);
  563. while (list($key, $val) = each($$vname_post)) {
  564. $s .= "$key=" . displayvar($val) . "<br/>";
  565. }
  566. }
  567. if (isset($GLOBALS)) {
  568. $s .= "Globals:<br/>";
  569. reset($GLOBALS);
  570. while (list($key, $val) = each($GLOBALS)) {
  571. $s .= "$key=" . displayvar($val) . "<br/>";
  572. }
  573. }
  574. }
  575. // Massage content to make it vanilla WML compliant..
  576. $content = $this->content . $s;
  577. $content = str_replace("<br>", "<br/>", $content);
  578. $content = strip_tags($content, "<br/><p><b><small>");
  579. $this->content = $content;
  580. return $this->content;
  581. }
  582. // ................................................................
  583. /**
  584. * Send debug output to a file.
  585. * @param string $name Filename to put output into
  586. * @param string $dir Directory/path to put file into
  587. */
  588. function send_to_file($name, $dir="") {
  589. if (!$this->debug_hascontent()) return;
  590. $s = $this->render();
  591. $f = new outputfile($name, $dir);
  592. if ($f->opened) {
  593. $f->write($this->content);
  594. $f->closefile();
  595. }
  596. }
  597. } // webdebugger class
  598. // ------------------------------------------------------------------
  599. // FUNCTIONS DEBUGGER INTERFACE
  600. // Debugging functions. These are just an interface
  601. // to our debugger for the client..
  602. // ------------------------------------------------------------------
  603.  
  604. /**
  605. * Add content to debug content
  606. * Adds the string content to the debugger output. This is done
  607. * in raw fashion without any <br> or linefeed chars appended.
  608. * The output will then appear as per the output settings.
  609. * @see debugbr()
  610. * @param string $content Content to add to debug output buffer
  611. * @param integer $debugclass Class of output
  612. */
  613. function debug($content, $debugclass=DBG_DIAGNOSTIC) {
  614. global $RESPONSE;
  615. if (isset($RESPONSE)) {
  616. $RESPONSE->debugger->debug_write($content, $debugclass);
  617. }
  618. }
  619. // ..................................................................
  620. /**
  621. * Add content to debug content with <br>
  622. * Adds the string content to the debugger output and appends
  623. * <br> to it. This is intended for output to HTML pages.
  624. * @see debug()
  625. * @param string $content Content to add to debug output buffer
  626. * @param integer $debugclass Class of output
  627. */
  628. function debugbr($content, $debugclass=DBG_DIAGNOSTIC) {
  629. debug($content . "<br>", $debugclass);
  630. }
  631. // ..................................................................
  632. /**
  633. * Add string to debug content as hexdump
  634. * Add string content to output as a hexdump. This is for
  635. * string data only. use this when you want to see 'inside'
  636. * a string variable and view the characters as hexadecimal
  637. * highlighted according to hex range. Chars are highlighted
  638. * as follows:
  639. * ASCII value = 32 (Spaces) ......... Blue
  640. * ASCII values < 32 (Control chars) .. Red
  641. * ASCII values > 127 ................. Green
  642. * @param string $str String to view as hex
  643. * @param string $msg Message to title the dump with
  644. * @param integer $debugclass Class of output
  645. */
  646. function debug_hex($str, $msg="", $debugclass=DBG_DIAGNOSTIC) {
  647. if (is_string($str)) {
  648. if ($msg != "") {
  649. debugbr($msg, $debugclass);
  650. }
  651. debug("<pre>", $debugclass);
  652. for ($i=0; $i < strlen($str); $i++) {
  653. $c = ord(substr($str, $i, 1));
  654. $xc = sprintf("%02x", $c);
  655. if ($c == 32) $xc = "<font color=blue>$xc</font>";
  656. elseif ($c < 32) $xc = "<font color=red>$xc</font>";
  657. elseif ($c > 127) $xc = "<font color=green>$xc</font>";
  658. debug("$xc|", $debugclass);
  659. if (($i + 1) % 16 == 0) debugbr("", $debugclass);
  660. }
  661. debug("</pre><br>", $debugclass);
  662. }
  663. }
  664. // ..................................................................
  665. /**
  666. * Set debugging class(es)
  667. * Sets the class or classes (OR'ed together) of debug output
  668. * which will be accepted/rendered on ouput.
  669. * @param integer $debugclass Class of output
  670. */
  671. function debug_class($debugclass="") {
  672. global $RESPONSE;
  673. $currentclass = DBG_UNDEFINED;
  674. if (isset($RESPONSE)) {
  675. if ($debugclass != "") {
  676. $RESPONSE->debugger->debug_class($debugclass);
  677. }
  678. $currentclass = $RESPONSE->debugger->debugclass;
  679. }
  680. // Return current class setting..
  681. return $currentclass;
  682. }
  683. // ..................................................................
  684. /**
  685. * Set debugging on
  686. * Sets the debugging on. Sets class(es) to accept.
  687. * @param integer $debugclass Class of output
  688. */
  689. function debug_on($debugclass=DBG_DEFAULT) {
  690. global $RESPONSE;
  691. if (isset($RESPONSE)) {
  692. $RESPONSE->debugger->debug_mode(ON, $debugclass);
  693. }
  694. }
  695. // ..................................................................
  696. /**
  697. * Set debugging off
  698. */
  699. function debug_off() {
  700. global $RESPONSE;
  701. if (isset($RESPONSE)) {
  702. $RESPONSE->debugger->debug_mode(OFF);
  703. }
  704. }
  705. // ..................................................................
  706. /**
  707. * Sets flag for debugger to include global vars in output.
  708. */
  709. // Causes page vars to be dumped..
  710. function debug_dump() {
  711. global $RESPONSE;
  712. if (isset($RESPONSE)) {
  713. $RESPONSE->debugger->debug_dump();
  714. }
  715. }
  716. // ..................................................................
  717. /**
  718. * Render the debug output as a string.
  719. * Normally debug output is taken care of by the system, however
  720. * you might need to get hold of the output for some reason, and
  721. * this is the function to do it.
  722. * @return string Debugger content as a string
  723. */
  724. function debug_render() {
  725. global $RESPONSE;
  726. if (isset($RESPONSE) && debugging()) {
  727. return $RESPONSE->debugger->render();
  728. }
  729. else return "";
  730. }
  731. // ..................................................................
  732. /**
  733. * Return debugger status
  734. * Function for external routines to determine
  735. * whether debugging is enabled or not..
  736. * @return boolean True if debugging is enabled
  737. */
  738. function debugging() {
  739. global $RESPONSE;
  740. if (isset($RESPONSE)) {
  741. return $RESPONSE->debugger->enabled;
  742. }
  743. }
  744. // ..................................................................
  745. /**
  746. * Set debugger output mode
  747. * This function allows setting of the debugger output
  748. * mode which determines where output goes.
  749. * @param integer $mode The debugger output mode
  750. */
  751. function debug_output($mode=DBG_O_DEFAULT) {
  752. global $RESPONSE;
  753. if (isset($RESPONSE)) {
  754. $RESPONSE->debugger->debug_output($mode);
  755. }
  756. }
  757. // ..................................................................
  758. /**
  759. * Calls Php phpinfo() function
  760. */
  761. function debug_phpinfo() {
  762. phpinfo(INFO_GENERAL|INFO_ENVIRONMENT|INFO_VARIABLES);
  763. }
  764. // ..................................................................
  765. /**
  766. * Display a variable nicely
  767. * Variables might be other than simple scalars. This function
  768. * is used internally by the debugger to make sure we show
  769. * them off in their best light.
  770. * @param mixed $var The variable to show off
  771. */
  772. function displayvar($var) {
  773. $s = "";
  774. if (is_array($var)) {
  775. foreach ($var as $elem) {
  776. $s .= "[$elem] ";
  777. }
  778. }
  779. elseif (is_bool($var)) {
  780. if ($var === true) $s .= "true";
  781. else $s .= "false";
  782. }
  783. else $s .= $var;
  784. return $s;
  785. }
  786. // ..................................................................
  787. /**
  788. * Insert an entry into the profiler. This label will have a line in
  789. * the profile output against the time elapsed since the last line.
  790. */
  791. function debug_profile($label) {
  792. global $RESPONSE;
  793. if (isset($RESPONSE) && $RESPONSE->debugger->profiling()) {
  794. $RESPONSE->debugger->profile($label);
  795. }
  796. }
  797. // ..................................................................
  798. /** Returns true if the RESPONSE is in profiling mode */
  799. debug_profiling() {
  800. global $RESPONSE;
  801. return ( isset($RESPONSE) && $RESPONSE->debugger->profiling() );
  802. }
  803. // ..................................................................
  804. /**
  805. * DEBUG TRACEBACK
  806. * Usage: In your function you bracket the statements you want to
  807. * label for tracing as in the following example..
  808. * function thing() {
  809. * debug_trace("mymodule"); // pushes "mymodule" on trace stack
  810. * ...blah blah // program statements
  811. * debug_trace(); // pops current trace off trace stack
  812. * }
  813. * NOTE: You can also use the object identifier for a class instead
  814. * of a simple string like "mymodule". For example:
  815. * function thing() {
  816. * debug_trace($this); // pushes name of object class on trace stack
  817. * ...blah blah // program statements
  818. * debug_trace(); // pops current trace off trace stack
  819. * }
  820. * @param mixed $traceobj Optional object trace is called in
  821. */
  822. function debug_trace($traceobj="") {
  823. global $RESPONSE;
  824. if (isset($RESPONSE)) {
  825. if ($traceobj == "") {
  826. return $RESPONSE->debugger->poptrace();
  827. }
  828. else {
  829. return $RESPONSE->debugger->pushtrace($traceobj);
  830. }
  831. }
  832. }
  833.  
  834. // ------------------------------------------------------------------
  835. ?>

Documentation generated by phpDocumentor 1.3.0RC3