Skip to content

Commit

Permalink
fixed bugs in browscap that prevented cache hits.
Browse files Browse the repository at this point in the history
stored browscap object in service layer
added profiler and API methods
  • Loading branch information
padams committed Jan 30, 2010
1 parent 1b6052e commit b654194
Show file tree
Hide file tree
Showing 24 changed files with 1,878 additions and 39 deletions.
101 changes: 101 additions & 0 deletions includes/pqp/README.txt
Original file line number Diff line number Diff line change
@@ -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!
90 changes: 90 additions & 0 deletions includes/pqp/classes/Console.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

/* - - - - - - - - - - - - - - - - - - - - -
Title : PHP Quick Profiler Console Class
Author : Created by Ryan Campbell
URL : http://particletree.com/features/php-quick-profiler/
Last Updated : April 22, 2009
Description : This class serves as a wrapper around a global
php variable, debugger_logs, that we have created.
- - - - - - - - - - - - - - - - - - - - - */

class Console {

/*-----------------------------------
LOG A VARIABLE TO CONSOLE
------------------------------------*/

public static function log($data) {
$logItem = array(
"data" => $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'];
}
}

?>
115 changes: 115 additions & 0 deletions includes/pqp/classes/MySqlDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

/* - - - - - - - - - - - - - - - - - - - - -
Title : PHP Quick Profiler MySQL Class
Author : Created by Ryan Campbell
URL : http://particletree.com/features/php-quick-profiler/
Last Updated : April 22, 2009
Description : A simple database wrapper that includes
logging of queries.
- - - - - - - - - - - - - - - - - - - - - */

class MySqlDatabase {

private $host;
private $user;
private $password;
private $database;
public $queryCount = 0;
public $queries = array();
public $conn;

/*------------------------------------
CONFIG CONNECTION
------------------------------------*/

function __construct($host, $user, $password) {
$this->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);
}

}

?>
Loading

0 comments on commit b654194

Please sign in to comment.