diff --git a/includes/pqp/README.txt b/includes/pqp/README.txt new file mode 100644 index 000000000..a01c8cf93 --- /dev/null +++ b/includes/pqp/README.txt @@ -0,0 +1,101 @@ +PHP Quick Profiler README +http://particletree.com/features/php-quick-profiler/ + +#### On This Page #### + +1. Introduction and Overview of Files +2. Getting the Example Working +3. Setting up the Database Class +4. Using Smarty instead of PHP echos + +##################################### +1. Introduction and Overview of Files +##################################### + +PHP Quick Profiler is a helper class that outputs debugging related information +to the screen when the page has finished executing. This zip package contains a +functional example project that utilizes the helper classes. + +- index.php : The landing page of the example. Navigate to it in your browser to see the demo. +- display.php : Contains the markup for PQP. +- pqp.tpl : A Smarty variation of the PQP markup. +- /css/ : The stylesheets used by PQP. +- /images/ : The images used by PQP. +- /classes/Console.php : The class used to log items to the PQP display. +- /classes/MySqlDatabase : A sample database wrapper to explain how database logging could be implemented. +- /classes/PhpQuickProfiler : The core class that compiles the data before outputting to the browser. + +############################## +2. Getting the Example Working +############################## + +For the most part, the example will work once you drop it in your root directory. +There are a few settings to check though. + +- In PHPQuickProfiler.php, set the $config member variable to the path relative to your root (located in the constructor). +- If PQP does not appear after navigating to index.php in your browser, locate the destructor +of the PQPExample class (at the bottom). Rename the function from __destruct() to display(). Then, +manually call the function display() just underneath the class after the call to init(). The reason this would +happen is because the destructor is not firing on your server configuration. +- At this point, everything should work except for the database tab. + +################################ +3. Setting up the Database Class +################################ + +NOTE - This step does require knowledge on PHP / Database interactions. There is no copy/paste solution. + +Logging database data is by far the hardest part of integrating PQP into your own project. It +requires that you have some sort of database wrapper around your code. If you do, it should be easy to implement. +To show you how it works, follow these steps with the sample database class we have provided. + +- Create a database named 'test' and run the following query on it. + +CREATE TABLE `Posts` ( + `PostId` int(11) unsigned NOT NULL default '0', + PRIMARY KEY (`PostId`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + +- In index.php, uncomment out the second include, which includes the database class. +- In index.php, uncomment out the function sampleDatabaseData(). +- In the sampleDatabaseData(), supply your database host, username, password, and database name. + +Given those steps, database logging will be enabled. If you would like to transition this to your own database class, +open /classes/MySqlDatabase.php and note the following: + +- $queryCount and $queries member variables declared on initialization +- When a query is run, the following is executed: + +$start = $this->getTime(); +$rs = mysql_query($sql, $this->conn); +$this->queryCount += 1; +$this->logQuery($sql, $start); + +- Everything in /classes/MySqlDatabase.php under the section comment "Debugging" +must be available for the above snippet to work. + +#################################### +4. Using Smarty instead of PHP echos +#################################### + +We love Smarty and hate echos, but to make this work for everyone we set the default as echos. To show love +to the Smarty users out there, we have included a pqp.tpl file for PQP. To make it work, you would have to change +the following in /classes/PhpQuickProfiler.php: + +- Add a require_once to your Smarty Library. +- In the constructor, declare an instance of Smarty: $this->smarty = new Smarty(...); +- Everywhere in in the code you see $this->output[... change it to a smarty assign. For example: + +$this->output['logs'] = $logs; + +... becomes ... + +$this->smarty->assign('logs', $logs); + +After doing it once, you'll see the pattern and can probably use a find/replace to do the rest quickly. + +- Locate the display() function at the bottom. Remove the last 2 lines, and add: + +$this->smarty->display('pathToDisplay.tpl'); + +All set after that! diff --git a/includes/pqp/classes/Console.php b/includes/pqp/classes/Console.php new file mode 100644 index 000000000..965adc8ea --- /dev/null +++ b/includes/pqp/classes/Console.php @@ -0,0 +1,90 @@ + $data, + "type" => 'log' + ); + $GLOBALS['debugger_logs']['console'][] = $logItem; + $GLOBALS['debugger_logs']['logCount'] += 1; + } + + /*--------------------------------------------------- + LOG MEMORY USAGE OF VARIABLE OR ENTIRE SCRIPT + -----------------------------------------------------*/ + + public function logMemory($object = false, $name = 'PHP') { + $memory = memory_get_usage(); + if($object) $memory = strlen(serialize($object)); + $logItem = array( + "data" => $memory, + "type" => 'memory', + "name" => $name, + "dataType" => gettype($object) + ); + $GLOBALS['debugger_logs']['console'][] = $logItem; + $GLOBALS['debugger_logs']['memoryCount'] += 1; + } + + /*----------------------------------- + LOG A PHP EXCEPTION OBJECT + ------------------------------------*/ + + public function logError($exception, $message) { + $logItem = array( + "data" => $message, + "type" => 'error', + "file" => $exception->getFile(), + "line" => $exception->getLine() + ); + $GLOBALS['debugger_logs']['console'][] = $logItem; + $GLOBALS['debugger_logs']['errorCount'] += 1; + } + + /*------------------------------------ + POINT IN TIME SPEED SNAPSHOT + -------------------------------------*/ + + public function logSpeed($name = 'Point in Time') { + $logItem = array( + "data" => PhpQuickProfiler::getMicroTime(), + "type" => 'speed', + "name" => $name + ); + $GLOBALS['debugger_logs']['console'][] = $logItem; + $GLOBALS['debugger_logs']['speedCount'] += 1; + } + + /*----------------------------------- + SET DEFAULTS & RETURN LOGS + ------------------------------------*/ + + public function getLogs() { + if(!$GLOBALS['debugger_logs']['memoryCount']) $GLOBALS['debugger_logs']['memoryCount'] = 0; + if(!$GLOBALS['debugger_logs']['logCount']) $GLOBALS['debugger_logs']['logCount'] = 0; + if(!$GLOBALS['debugger_logs']['speedCount']) $GLOBALS['debugger_logs']['speedCount'] = 0; + if(!$GLOBALS['debugger_logs']['errorCount']) $GLOBALS['debugger_logs']['errorCount'] = 0; + return $GLOBALS['debugger_logs']; + } +} + +?> \ No newline at end of file diff --git a/includes/pqp/classes/MySqlDatabase.php b/includes/pqp/classes/MySqlDatabase.php new file mode 100644 index 000000000..51225a7c3 --- /dev/null +++ b/includes/pqp/classes/MySqlDatabase.php @@ -0,0 +1,115 @@ +host = $host; + $this->user = $user; + $this->password = $password; + } + + function connect($new = false) { + $this->conn = mysql_connect($this->host, $this->user, $this->password, $new); + if(!$this->conn) { + throw new Exception('We\'re working on a few connection issues.'); + } + } + + function changeDatabase($database) { + $this->database = $database; + if($this->conn) { + if(!mysql_select_db($database, $this->conn)) { + throw new CustomException('We\'re working on a few connection issues.'); + } + } + } + + function lazyLoadConnection() { + $this->connect(true); + if($this->database) $this->changeDatabase($this->database); + } + + /*----------------------------------- + QUERY + ------------------------------------*/ + + function query($sql) { + if(!$this->conn) $this->lazyLoadConnection(); + $start = $this->getTime(); + $rs = mysql_query($sql, $this->conn); + $this->queryCount += 1; + $this->logQuery($sql, $start); + if(!$rs) { + throw new Exception('Could not execute query.'); + } + return $rs; + } + + /*----------------------------------- + DEBUGGING + ------------------------------------*/ + + function logQuery($sql, $start) { + $query = array( + 'sql' => $sql, + 'time' => ($this->getTime() - $start)*1000 + ); + array_push($this->queries, $query); + } + + function getTime() { + $time = microtime(); + $time = explode(' ', $time); + $time = $time[1] + $time[0]; + $start = $time; + return $start; + } + + public function getReadableTime($time) { + $ret = $time; + $formatter = 0; + $formats = array('ms', 's', 'm'); + if($time >= 1000 && $time < 60000) { + $formatter = 1; + $ret = ($time / 1000); + } + if($time >= 60000) { + $formatter = 2; + $ret = ($time / 1000) / 60; + } + $ret = number_format($ret,3,'.','') . ' ' . $formats[$formatter]; + return $ret; + } + + function __destruct() { + @mysql_close($this->conn); + } + +} + +?> diff --git a/includes/pqp/classes/PhpQuickProfiler.php b/includes/pqp/classes/PhpQuickProfiler.php new file mode 100644 index 000000000..9b77d5b71 --- /dev/null +++ b/includes/pqp/classes/PhpQuickProfiler.php @@ -0,0 +1,204 @@ +startTime = $startTime; + $this->config = $config; + require_once($config.'classes/Console.php'); + } + + /*------------------------------------------- + FORMAT THE DIFFERENT TYPES OF LOGS + -------------------------------------------*/ + + public function gatherConsoleData() { + $logs = Console::getLogs(); + if($logs['console']) { + foreach($logs['console'] as $key => $log) { + if($log['type'] == 'log') { + $logs['console'][$key]['data'] = print_r($log['data'], true); + } + elseif($log['type'] == 'memory') { + $logs['console'][$key]['data'] = $this->getReadableFileSize($log['data']); + } + elseif($log['type'] == 'speed') { + $logs['console'][$key]['data'] = $this->getReadableTime(($log['data'] - $this->startTime)*1000); + } + } + } + $this->output['logs'] = $logs; + } + + /*------------------------------------------- + AGGREGATE DATA ON THE FILES INCLUDED + -------------------------------------------*/ + + public function gatherFileData() { + $files = get_included_files(); + $fileList = array(); + $fileTotals = array( + "count" => count($files), + "size" => 0, + "largest" => 0, + ); + + foreach($files as $key => $file) { + $size = filesize($file); + $fileList[] = array( + 'name' => $file, + 'size' => $this->getReadableFileSize($size) + ); + $fileTotals['size'] += $size; + if($size > $fileTotals['largest']) $fileTotals['largest'] = $size; + } + + $fileTotals['size'] = $this->getReadableFileSize($fileTotals['size']); + $fileTotals['largest'] = $this->getReadableFileSize($fileTotals['largest']); + $this->output['files'] = $fileList; + $this->output['fileTotals'] = $fileTotals; + } + + /*------------------------------------------- + MEMORY USAGE AND MEMORY AVAILABLE + -------------------------------------------*/ + + public function gatherMemoryData() { + $memoryTotals = array(); + $memoryTotals['used'] = $this->getReadableFileSize(memory_get_peak_usage()); + $memoryTotals['total'] = ini_get("memory_limit"); + $this->output['memoryTotals'] = $memoryTotals; + } + + /*-------------------------------------------------------- + QUERY DATA -- DATABASE OBJECT WITH LOGGING REQUIRED + ----------------------------------------------------------*/ + + public function gatherQueryData() { + $queryTotals = array(); + $queryTotals['count'] = 0; + $queryTotals['time'] = 0; + $queries = array(); + + if($this->db != '') { + $queryTotals['count'] += $this->db->queryCount; + foreach($this->db->queries as $key => $query) { + $query = $this->attemptToExplainQuery($query); + $queryTotals['time'] += $query['time']; + $query['time'] = $this->getReadableTime($query['time']); + $queries[] = $query; + } + } + + $queryTotals['time'] = $this->getReadableTime($queryTotals['time']); + $this->output['queries'] = $queries; + $this->output['queryTotals'] = $queryTotals; + } + + /*-------------------------------------------------------- + CALL SQL EXPLAIN ON THE QUERY TO FIND MORE INFO + ----------------------------------------------------------*/ + + function attemptToExplainQuery($query) { + try { + $sql = 'EXPLAIN '.$query['sql']; + $rs = $this->db->query($sql); + } + catch(Exception $e) {} + if($rs) { + $row = mysql_fetch_array($rs, MYSQL_ASSOC); + $query['explain'] = $row; + } + return $query; + } + + /*------------------------------------------- + SPEED DATA FOR ENTIRE PAGE LOAD + -------------------------------------------*/ + + public function gatherSpeedData() { + $speedTotals = array(); + $speedTotals['total'] = $this->getReadableTime(($this->getMicroTime() - $this->startTime)*1000); + $speedTotals['allowed'] = ini_get("max_execution_time"); + $this->output['speedTotals'] = $speedTotals; + } + + /*------------------------------------------- + HELPER FUNCTIONS TO FORMAT DATA + -------------------------------------------*/ + + function getMicroTime() { + $time = microtime(); + $time = explode(' ', $time); + return $time[1] + $time[0]; + } + + public function getReadableFileSize($size, $retstring = null) { + // adapted from code at http://aidanlister.com/repos/v/function.size_readable.php + $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); + + if ($retstring === null) { $retstring = '%01.2f %s'; } + + $lastsizestring = end($sizes); + + foreach ($sizes as $sizestring) { + if ($size < 1024) { break; } + if ($sizestring != $lastsizestring) { $size /= 1024; } + } + if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional + return sprintf($retstring, $size, $sizestring); + } + + public function getReadableTime($time) { + $ret = $time; + $formatter = 0; + $formats = array('ms', 's', 'm'); + if($time >= 1000 && $time < 60000) { + $formatter = 1; + $ret = ($time / 1000); + } + if($time >= 60000) { + $formatter = 2; + $ret = ($time / 1000) / 60; + } + $ret = number_format($ret,3,'.','') . ' ' . $formats[$formatter]; + return $ret; + } + + /*--------------------------------------------------------- + DISPLAY TO THE SCREEN -- CALL WHEN CODE TERMINATING + -----------------------------------------------------------*/ + + public function display($db = '', $master_db = '') { + $this->db = $db; + $this->master_db = $master_db; + $this->gatherConsoleData(); + $this->gatherFileData(); + $this->gatherMemoryData(); + $this->gatherQueryData(); + $this->gatherSpeedData(); + require_once($this->config.'display.php'); + displayPqp($this->output, OWA_PUBLIC_URL.'includes/pqp/'); + } + +} + +?> \ No newline at end of file diff --git a/includes/pqp/css/pQp.css b/includes/pqp/css/pQp.css new file mode 100644 index 000000000..8d9c68bb0 --- /dev/null +++ b/includes/pqp/css/pQp.css @@ -0,0 +1,406 @@ +/* - - - - - - - - - - - - - - - - - - - - - + + Title : PHP Quick Profiler CSS + Author : Designed by Kevin Hale. + URL : http://particletree.com/features/php-quick-profiler/ + + Last Updated : April 21, 2009 + +- - - - - - - - - - - - - - - - - - - - - */ + +.pQp{ + width:100%; + text-align:center; + position:fixed; + bottom:0; +} +* html .pQp{ + position:absolute; +} +.pQp *{ + margin:0; + padding:0; + border:none; +} +#pQp{ + margin:0 auto; + width:85%; + min-width:960px; + background-color:#222; + border:12px solid #000; + border-bottom:none; + font-family:"Lucida Grande", Tahoma, Arial, sans-serif; + -webkit-border-top-left-radius:15px; + -webkit-border-top-right-radius:15px; + -moz-border-radius-topleft:15px; + -moz-border-radius-topright:15px; +} +#pQp .pqp-box h3{ + font-weight:normal; + line-height:200px; + padding:0 15px; + color:#fff; +} +.pQp, .pQp td{ + color:#444; +} + +/* ----- IDS ----- */ + +#pqp-metrics{ + background:#000; + width:100%; +} +#pqp-console, #pqp-speed, #pqp-queries, #pqp-memory, #pqp-files{ + background:url(../images/overlay.gif); + border-top:1px solid #ccc; + height:200px; + overflow:auto; +} + +/* ----- Colors ----- */ + +.pQp .green{color:#588E13 !important;} +.pQp .blue{color:#3769A0 !important;} +.pQp .purple{color:#953FA1 !important;} +.pQp .orange{color:#D28C00 !important;} +.pQp .red{color:#B72F09 !important;} + +/* ----- Logic ----- */ + +#pQp, #pqp-console, #pqp-speed, #pqp-queries, #pqp-memory, #pqp-files{ + display:none; +} +.pQp .console, .pQp .speed, .pQp .queries, .pQp .memory, .pQp .files{ + display:block !important; +} +.pQp .console #pqp-console, .pQp .speed #pqp-speed, .pQp .queries #pqp-queries, +.pQp .memory #pqp-memory, .pQp .files #pqp-files{ + display:block; +} +.console td.green, .speed td.blue, .queries td.purple, .memory td.orange, .files td.red{ + background:#222 !important; + border-bottom:6px solid #fff !important; + cursor:default !important; +} + +.tallDetails #pQp .pqp-box{ + height:500px; +} +.tallDetails #pQp .pqp-box h3{ + line-height:500px; +} +.hideDetails #pQp .pqp-box{ + display:none !important; +} +.hideDetails #pqp-footer{ + border-top:1px dotted #444; +} +.hideDetails #pQp #pqp-metrics td{ + height:50px; + background:#000 !important; + border-bottom:none !important; + cursor:default !important; +} +.hideDetails #pQp var{ + font-size:18px; + margin:0 0 2px 0; +} +.hideDetails #pQp h4{ + font-size:10px; +} +.hideDetails .heightToggle{ + visibility:hidden; +} + +/* ----- Metrics ----- */ + +#pqp-metrics td{ + height:80px; + width:20%; + text-align:center; + cursor:pointer; + border:1px solid #000; + border-bottom:6px solid #444; + -webkit-border-top-left-radius:10px; + -moz-border-radius-topleft:10px; + -webkit-border-top-right-radius:10px; + -moz-border-radius-topright:10px; +} +#pqp-metrics td:hover{ + background:#222; + border-bottom:6px solid #777; +} +#pqp-metrics .green{ + border-left:none; +} +#pqp-metrics .red{ + border-right:none; +} + +#pqp-metrics h4{ + text-shadow:#000 1px 1px 1px; +} +.side var{ + text-shadow:#444 1px 1px 1px; +} + +.pQp var{ + font-size:23px; + font-weight:bold; + font-style:normal; + margin:0 0 3px 0; + display:block; +} +.pQp h4{ + font-size:12px; + color:#fff; + margin:0 0 4px 0; +} + +/* ----- Main ----- */ + +.pQp .main{ + width:80%; +} +*+html .pQp .main{ + width:78%; +} +* html .pQp .main{ + width:77%; +} +.pQp .main td{ + padding:7px 15px; + text-align:left; + background:#151515; + border-left:1px solid #333; + border-right:1px solid #333; + border-bottom:1px dotted #323232; + color:#FFF; +} +.pQp .main td, pre{ + font-family:Monaco, "Consolas", "Lucida Console", "Courier New", monospace; + font-size:11px; +} +.pQp .main td.alt{ + background:#111; +} +.pQp .main tr.alt td{ + background:#2E2E2E; + border-top:1px dotted #4E4E4E; +} +.pQp .main tr.alt td.alt{ + background:#333; +} +.pQp .main td b{ + float:right; + font-weight:normal; + color:#E6F387; +} +.pQp .main td:hover{ + background:#2E2E2E; +} + +/* ----- Side ----- */ + +.pQp .side{ + float:left; + width:20%; + background:#000; + color:#fff; + -webkit-border-bottom-left-radius:30px; + -moz-border-radius-bottomleft:30px; + text-align:center; +} +.pQp .side td{ + padding:10px 0 5px 0; + background:url(../images/side.png) repeat-y right; +} +.pQp .side var{ + color:#fff; + font-size:15px; +} +.pQp .side h4{ + font-weight:normal; + color:#F4FCCA; + font-size:11px; +} + +/* ----- Console ----- */ + +#pqp-console .side td{ + padding:12px 0; +} +#pqp-console .side td.alt1{ + background:#588E13; + width:51%; +} +#pqp-console .side td.alt2{ + background-color:#B72F09; +} +#pqp-console .side td.alt3{ + background:#D28C00; + border-bottom:1px solid #9C6800; + border-left:1px solid #9C6800; + -webkit-border-bottom-left-radius:30px; + -moz-border-radius-bottomleft:30px; +} +#pqp-console .side td.alt4{ + background-color:#3769A0; + border-bottom:1px solid #274B74; +} + +#pqp-console .main table{ + width:100%; +} +#pqp-console td div{ + width:100%; + overflow:hidden; +} +#pqp-console td.type{ + font-family:"Lucida Grande", Tahoma, Arial, sans-serif; + text-align:center; + text-transform: uppercase; + font-size:9px; + padding-top:9px; + color:#F4FCCA; + vertical-align:top; + width:40px; +} +.pQp .log-log td.type{ + background:#47740D !important; +} +.pQp .log-error td.type{ + background:#9B2700 !important; +} +.pQp .log-memory td.type{ + background:#D28C00 !important; +} +.pQp .log-speed td.type{ + background:#2B5481 !important; +} + +.pQp .log-log pre{ + color:#999; +} +.pQp .log-log td:hover pre{ + color:#fff; +} + +.pQp .log-memory em, .pQp .log-speed em{ + float:left; + font-style:normal; + display:block; + color:#fff; +} +.pQp .log-memory pre, .pQp .log-speed pre{ + float:right; + white-space: normal; + display:block; + color:#FFFD70; +} + +/* ----- Speed ----- */ + +#pqp-speed .side td{ + padding:12px 0; +} +#pqp-speed .side{ + background-color:#3769A0; +} +#pqp-speed .side td.alt{ + background-color:#2B5481; + border-bottom:1px solid #1E3C5C; + border-left:1px solid #1E3C5C; + -webkit-border-bottom-left-radius:30px; + -moz-border-radius-bottomleft:30px; +} + +/* ----- Queries ----- */ + +#pqp-queries .side{ + background-color:#953FA1; + border-bottom:1px solid #662A6E; + border-left:1px solid #662A6E; +} +#pqp-queries .side td.alt{ + background-color:#7B3384; +} +#pqp-queries .main b{ + float:none; +} +#pqp-queries .main em{ + display:block; + padding:2px 0 0 0; + font-style:normal; + color:#aaa; +} + +/* ----- Memory ----- */ + +#pqp-memory .side td{ + padding:12px 0; +} +#pqp-memory .side{ + background-color:#C48200; +} +#pqp-memory .side td.alt{ + background-color:#AC7200; + border-bottom:1px solid #865900; + border-left:1px solid #865900; + -webkit-border-bottom-left-radius:30px; + -moz-border-radius-bottomleft:30px; +} + +/* ----- Files ----- */ + +#pqp-files .side{ + background-color:#B72F09; + border-bottom:1px solid #7C1F00; + border-left:1px solid #7C1F00; +} +#pqp-files .side td.alt{ + background-color:#9B2700; +} + +/* ----- Footer ----- */ + +#pqp-footer{ + width:100%; + background:#000; + font-size:11px; + border-top:1px solid #ccc; +} +#pqp-footer td{ + padding:0 !important; + border:none !important; +} +#pqp-footer strong{ + color:#fff; +} +#pqp-footer a{ + color:#999; + padding:5px 10px; + text-decoration:none; +} +#pqp-footer .credit{ + width:20%; + text-align:left; +} +#pqp-footer .actions{ + width:80%; + text-align:right; +} +#pqp-footer .actions a{ + float:right; + width:auto; +} +#pqp-footer a:hover, #pqp-footer a:hover strong, #pqp-footer a:hover b{ + background:#fff; + color:blue !important; + text-decoration:underline; +} +#pqp-footer a:active, #pqp-footer a:active strong, #pqp-footer a:active b{ + background:#ECF488; + color:green !important; +} \ No newline at end of file diff --git a/includes/pqp/display.php b/includes/pqp/display.php new file mode 100644 index 000000000..9a1ee93bc --- /dev/null +++ b/includes/pqp/display.php @@ -0,0 +1,350 @@ + + +JAVASCRIPT; + +echo '
'; + +} + +?> \ No newline at end of file diff --git a/includes/pqp/images/overlay.gif b/includes/pqp/images/overlay.gif new file mode 100644 index 000000000..8674fa544 Binary files /dev/null and b/includes/pqp/images/overlay.gif differ diff --git a/includes/pqp/images/side.png b/includes/pqp/images/side.png new file mode 100644 index 000000000..08243e2b5 Binary files /dev/null and b/includes/pqp/images/side.png differ diff --git a/includes/pqp/index.php b/includes/pqp/index.php new file mode 100644 index 000000000..05da7fca4 --- /dev/null +++ b/includes/pqp/index.php @@ -0,0 +1,178 @@ +profiler = new PhpQuickProfiler(PhpQuickProfiler::getMicroTime()); + } + + public function init() { + $this->sampleConsoleData(); + $this->sampleDatabaseData(); + $this->sampleMemoryLeak(); + $this->sampleSpeedComparison(); + } + + /*------------------------------------------- + EXAMPLES OF THE 4 CONSOLE FUNCTIONS + -------------------------------------------*/ + + public function sampleConsoleData() { + try { + Console::log('Begin logging data'); + Console::logMemory($this, 'PQP Example Class : Line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::log(array('Name' => 'Ryan', 'Last' => 'Campbell')); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logMemory($this, 'PQP Example Class : Line '.__LINE__); + Console::log('Ending log below with a sample error.'); + throw new Exception('Unable to write to log!'); + } + catch(Exception $e) { + Console::logError($e, 'Sample error logging.'); + } + } + + /*------------------------------------- + DATABASE OBJECT TO LOG QUERIES + --------------------------------------*/ + + public function sampleDatabaseData() { + /*$this->db = new MySqlDatabase( + 'your DB host', + 'your DB user', + 'your DB password'); + $this->db->connect(true); + $this->db->changeDatabase('your db name'); + + $sql = 'SELECT PostId FROM Posts WHERE PostId > 2'; + $rs = $this->db->query($sql); + + $sql = 'SELECT COUNT(PostId) FROM Posts'; + $rs = $this->db->query($sql); + + $sql = 'SELECT COUNT(PostId) FROM Posts WHERE PostId != 1'; + $rs = $this->db->query($sql);*/ + } + + /*----------------------------------- + EXAMPLE MEMORY LEAK DETECTED + ------------------------------------*/ + + public function sampleMemoryLeak() { + $ret = ''; + $longString = 'This is a really long string that when appended with the . symbol + will cause memory to be duplicated in order to create the new string.'; + for($i = 0; $i < 10; $i++) { + $ret = $ret . $longString; + Console::logMemory($ret, 'Watch memory leak -- iteration '.$i); + } + } + + /*----------------------------------- + POINT IN TIME SPEED MARKS + ------------------------------------*/ + + public function sampleSpeedComparison() { + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + Console::logSpeed('Time taken to get to line '.__LINE__); + } + + public function __destruct() { + $this->profiler->display($this->db); + } + +} + +$pqp = new PQPExample(); +$pqp->init(); + +?> + + + + + +