Introduction

In our company, code reviews play an integral part in the development process for making quality software. We opt for a mentor style approach with Wufoo, where a developer works on a segment for a period of time and then passes it up to a more experienced developer for review. We really like this approach because it means more developers become familiar with the foundation of different code level services. More importantly, they act as an additional safeguard against security holes, memory leaks, poor queries and heavy file structures. Unfortunately, these reviews are also very time consuming and in a small team can sometimes be an inconvenience to the reviewer — another developer with their own todo list to accomplish.

HTML Form Builder

Given that all reviews check against the same list of requirements, we’ve found ourselves repeating the same tasks over and over again. We spend a lot of time echoing queries, memory stats and objects to the browser just to see how they are being used in the code. To reduce this repetition, we invested some time creating something we’ve called the PHP Quick Profiler—we call it PQP for short. It’s a small tool (think Firebug for PHP) to provide profiling and debugging related information to developers without needing them to add a lot of programmatic overhead to their code. Now, we only need to toggle one config setting to true and our reviewers have access to an automated tool to help create a faster and more consistent review experience. Since anyone can use it, PQP also gives the initial developer an idea of where their code stands before the review.

We’ve been using PQP for a while now with Wufoo. It’s been so useful that we decided to take some time to package everything, write out some documentation and offer it up for anyone to use.

See it in Action

We’ve created an online example showing a landing page with PQP turned on. The profiler contains a 5 tabbed interface that presents pages for logging messages, measuring execution time, analyzing queries, revealing memory used and showing the files included.

PHP Quick Profiler

Thanks to Kevin’s help, who did a great job of designing and encapsulating the interface, there’s no need here to add links to external CSS files or Scripts to make it show up right. When included on a page in PHP, PQP automatically inserts the markup, CSS and JavaScript needed to make the interface show up and just work. PQP should work with Internet Explorer 6 and up, Firefox and Safari.

Getting Started

We’ve provided a zip file which contains the entire setup for PQP and some basic instructions for installation.

Download: pqp.zip

Once you’ve downloaded the zip, upload the contents to a PHP enabled web server. Navigating to the root directory in your browser will show the same online example we linked to above. At this point, each tab should work except for the database tab, which requires some additional configuration.

Once you get the example working, the next step would be integration with your own project. It’s important to note that dropping the folder into your own project directory will not work. This is because 5 different aspects of the code are being looked at, and you may handle those situations differently than we do. That said, integration is pretty straightforward, and by following the guidelines for each section below, you should be up and running in no time.

Using It In Your Code

The easiest way to make PQP work in your own code is to include PhpQuickProfiler.php into the page you want to see it on. That alone will enable the console, memory and file logging. Speed and database logging take a bit more work, which we’ll cover later. Now, enabling the default logging is great, but nothing will display to the screen by just including the file. To display to the screen, a bit more knowledge on what’s happening is required.

As code is being executed, details are being logged and analyzed in PQP. Once the code is finished, PQP finishes up also, and displays the output to the screen. The tricky part is knowing when the code is finished, since in an ideal world this tool would work with as little developer input as possible. In this example, we determine that the code has finished by looking at when the parent object runs its destructor. So a timeline would be:

  • Landing Page constructor declares an instance of PhpQuickProfiler.
  • Landing Page executes all needed code.
  • Landing Page destructor tells the PhpQuickProfiler to cleanup and display output.

Of course, this setup would cause PQP to always display, which isn’t ideal for production. To make it more useful, we created a Config flag in our code (debugMode = true) that checks to make sure it is set to true before displaying. Below is a sample class that can perform the steps we just covered:

class ExampleLandingPage {    private $profiler;
    private $db;    public function __construct() {
        $this->profiler = new PhpQuickProfiler(PhpQuickProfiler::getMicroTime());
    }    public function __destruct() {
        if($debugMode == true) $this->profiler->display($this->db);
    }}

Logging to the Console

Given the code shell above, PQP is configured and ready to be used. We can start referencing the helper functions, starting with logging. The console log is just a step above an echo statement in that it condenses and formats the output using print_r. This is useful for reviewers because it provides a way to view debugging information without blowing up the layout of the page. To output data to the console, just statically call the function:

Console::log($data);

The static function call accepts any data type and is available as long as the PhpQuickProfiler.php class is included. We chose to implement this with a static call so that the class does not have to be instantiated before use. The downside to a static call is that we store the log history in a global php variable. Should you wish to avoid globals, the Console.php class could always hold the log as a member variable given that it is instantiated. But as is, the class just acts as a read and write wrapper around a global PHP variable.

On top of logging variables, the console also has four additional functions.

Console::logError($exception);
Console::logMemory();
Console::logMemory($variable, $name);
Console::logSpeed();

Let’s start with logError(). Logging an error is useful for displaying information related to a PHP exception. In our code, we’ll use a catch block for handling errors so we can silence an exception. We do this because we want that error to be ignored and not affect what the user is doing. An example of this would be logging data that isn’t crucial. If that log fails, the users shouldn’t have to stop what they’re doing. Now, in development, it’s still nice to know those exceptions were thrown, so in the catch block a call to logError() can be made to display the information to the console like so:

try {
    // Execute non critical code
}
catch(Exception $e) {
    Console::logError($e, 'Unable to execute non critical code');
}

Additionally, the console can provide even more value by using some of the helper functions that PHP natively provides. For example, logging debug_backtrace() will print related information about the script at a given point in time. PHP also provides us with magic constants like __LINE__, __FILE__, __FUNCTION__, __METHOD__ and __CLASS__, which allows for printing of script data. Take a look at the screenshot below to see some example usage of this:

PQP Height Expanded

Watching Memory Usage

Object oriented PHP is a beautiful thing to behold, but there are definitely a few concerns to keep in mind when it comes to memory usage. These concerns tend to rear their heads when dealing with recursive output (i.e.: exporting to Excel), if there’s a leak in the creation of the objects or if objects aren’t being destroyed properly. All of this can lead to unexpected resource usage and fatal errors that serve to aggravate the end user.

The debugger aids with memory management by displaying the maximum amount of memory used by the script. A simple call to the built in memory_get_peak_usage() is where the data originates. The system setting for memory allowed (through ini_get()) is also shown to see how much wiggle room there is. If an overview isn’t enough, you can drill down into your resource usage with a point in time memory call.

Console::logMemory();
Console::logMemory($variable, $name);

Calling logMemory() in your code without any parameters will output the current amount of memory that PHP is using when the function is called. This is perfect for watching a loop in your script to see if memory is building up during each iteration. Likewise, a variable and a name can be passed in to the function. Doing so will output the memory used by the variable to the console. Knowing that a script is hogging memory is wonderful, and knowing which variable is doing the hogging allows the problem to be fixed. Take a look at the screenshot below to see an example of string concatenation that is slowly eating up memory.

PQP Memory Usage

Runaway Includes

Similar to memory getting out of control, included files (especially on large complex projects) can multiply and take over your app before very quickly. Even worse, too many includes don’t throw the hard errors that memory usage does. Instead, the page just slows down and resources get eaten up on every request served. Avoiding this pitfall is pretty easy—just make sure the same file isn’t included multiple times, and catch any excessive includes of unnecessary files.

PQP File Includes

The PQP files tab shows the total files included with a count call on get_included_files and their total sizes are summed up. The names and sizes of the individual files are output to the console for easy scanning as well. The largest file included is noted on the left, which clearly points out if a large library is being used when it shouldn’t be. For example, on Wufoo we found out that we had a script always including htmLawed, a fairly decent sized file, when it wasn’t needed.

Also, keep in mind, autoloading classes or using require_once will usually alleviate any problems with file includes. That said, it never hurts to be aware of the situation, especially when using plugins, old code, or borrowed code.

Page Execution Time

Emphasis is always placed on database optimization when it comes to performance considerations (rightfully so), but that doesn’t mean PHP execution time should be ignored completely. The standard method for calculating load time is to find the difference between the time when the script starts and then again when the script finishes. This is where the integration of the debugger into your own project becomes tricky. Since the debugger is called on the destruction of the parent page, we know when the script is ending. But since every project is different, the start time can vary. The example code that you can download sets the start time in the construction of the parent object with a call to PQP’s getMicroTime(). This will work in most cases, but if you have a lot of code going on before the parent is constructed, be sure to specifically set the start time when needed.

$this->profiler = new PhpQuickProfiler(PhpQuickProfiler::getMicroTime());

Given the page execution time, the next step would be to find meaning in the information. A quick glance will show if the time falls into an acceptable range. Assuming it doesn’t, how would we go about debugging the problem? Using the query section of the debugger, we can rule out query execution time (explained more in the next section). If queries aren’t the problem, then some portion of the script is. We can find this with the console.

Console::logSpeed();

A call to logSpeed() will tell us how long the script has taken up until that point in time. For example, imagine we have an object factory that constructs complex objects from a database. We also have an object engine that returns the object names from a database. When displaying 100 objects names to the screen, we would use either the factory or the engine. But using the engine would be much faster because we only need the names, and do not need the logic processing of object creation. If the developer did use the factory, logSpeed() would reveal the slowdown in the display loop, which ultimately identifies the problem.

PQP Execution Time

On a similar note, we recently discovered that xCache improves our page execution time by over 60%. This was compared against other benchmarks by having all of our developers run quick tests against the code they were responsible for using PQP.

A Glance at Database Activity

Getting the debugger to report database information is the hardest part of integration with your own project. This step will only work if your database interaction is abstracted in some way. We talked about a simple database class awhile back, and have also released an example with the zip download (MySqlDatabase.php — you can follow the code in there to see a full implementation). The reason a class is so important is because information about each query must be stored as it happens, and a class allows the queries to each go through the same analysis without additional work by the programmer.

As a query is called, the database wrapper class stores the query and logs the time. The simplified code looks like this:

function query($sql) {
    $start = $this->getTime();
    $rs = mysql_query($sql, $this->conn);
    $this->logQuery($sql, $start);
    return $rs;
}function logQuery($sql, $start) {
    $query = array(
        'sql' => $sql,
        'time' => ($this->getTime() - $start)*1000
    );
    array_push($this->queries, $query);
}

Using that concept, the class will have an array of all query information available to it. Then, the debugger can take that array and print out the information. The information that is currently stored is the query itself, and the time to execute. The time to execute is not exact — it is the microtime until PHP has a handle on the recordset, which will be slower than the query time if there is network latency with the database server. Viewing the queries at a glance is an easy and helpful way to look for queries that would affect more records than intended, that are being duplicated or those that open themselves up to SQL injection.

One of the most useful database features added to the debugger is the ability to EXPLAIN each query run. Each query is run again using the explain statement, and the results are presented below the query. This makes it easy to identify which queries are using their indexes properly.

PQP Database Queries

Wrapping Up

The end goal of this debugging tool is to present a summary of useful information in an automated format. Usually, finding out about certain aspects of the code would require manual work and thought. And then if a problem is encountered, the debugger will hopefully make narrowing down the problem easier through the use of the extended Console functions. With that in mind, this tool is just an aid and is in no way meant to replace the standard, thorough procedures available to developers. The slow query log, PHP error log and full fledged debuggers and profilers are encouraged on top of this high level view to supplement the tools available to developers.

HTML Form Builder
Ryan Campbell

PHP Quick Profiler by Ryan Campbell

This entry was posted 2 years ago and was filed under Features.
Comments are currently closed.

· 134 Comments! ·

  1. Wesley · 2 years ago

    Awesomesauce! I had a basic class that does some similar things, but this is so much more advanced.

  2. Artem Russakovskii · 2 years ago

    I’m going to try this out (thanks @improvingtheweb for the link).

    BTW, you may want to either strip the .svn dirs from the release (svn export) or enable anonymous access so we can upgrade easily. Introducing versions would be great too.

    Thanks.

  3. Joel Nagy · 2 years ago

    Very exciting, I can’t wait to start using this in my applications.

  4. paul · 2 years ago

    Nicely done!

  5. Michael · 2 years ago

    Wow. This is exponentially cool!

  6. Ryan Campbell · 2 years ago

    Thanks for the heads up, Artem. Should be fixed now.

  7. Artem Russakovskii · 2 years ago

    Initial impressions after trying it out: awesome, beautiful, easy to use!

    Your guide doesn’t mention the PhpQuickProfiler constructor accepts a 2nd parameter, which is the path itself (any way to get around that, considering I already put in the path into the include once?). This is mentioned in the readme though.

    Keep up the good work and release it on google code or something similar please, so that we can follow the changelog and updates.

  8. steve · 2 years ago

    downloaded immediately… ready to install - looks !@#$ing fantastic! - can’t wait to “see” how bad my code is! ;-)

  9. George Larson · 2 years ago

    Everyone needs a hug.

  10. Maarten Hus · 2 years ago

    The demo doesn’t seem to work. The css does not get included.

    Add on line 121 in index.php

    To solve include error: change $config change to:

    PhpQuickProfiler.php line 23 public function __construct($startTime, $config = ‘PhpQuickProfiler/’) {

  11. Maarten Hus · 2 years ago

    PS my comment is bugged to you should include the css yourself.

    head link rel=”stylesheet” href=”css/pQp.css” type=”text/css” head

    PhpQuickProfiler.php line 23: public function __construct($startTime, $config = ‘PhpQuickProfiler/’) {

  12. steve · 2 years ago

    The zip file has the path set to “PhpQuickProfiler” but from the code it looks for {root}/pqp/

    I fixed it locally and am now enjoying the eye-candy / toys.

  13. Kevin Hale · 2 years ago

    Maarten, make sure you have JavaScript enabled on that page. The PQP is supposed to insert that link to the CSS file dynamically so you don’t have to. If you do have JS turned on, do you mind sharing what browser and operating system you’re using?

  14. KOGI · 2 years ago

    Very cool!! Downloading now!

  15. Kevin Hale · 2 years ago

    Ah, Steve, you’re right. We’re renaming the folder and putting it up now. Maarten, I’m betting that might have been the issue you were having.

  16. Ryan Campbell · 2 years ago

    Ok, the folder is now renamed so that it properly works by default. If your download isn’t giving you pqp.zip, try clearing your cache.

  17. Ross · 2 years ago

    AWESOME! I’m definitely going to be using this from now on - thanks!

  18. Josh · 2 years ago

    Very nice, can’t wait to give it a spin!

  19. Matthew Pennell · 2 years ago

    Excellent stuff - I can see this being very useful in an upcoming project.

    What license are you releasing this under? Can we fork it? I’d like to rework it for use with ExpressionEngine.

  20. Kevin Hale · 2 years ago

    All of our code on Particletree is released under a Creative Commons Attribution license. You can see it in the Readme file in the zip.

  21. Keith - SuPeR K! · 2 years ago

    I think you meant to link to http://particletree.com/files/pqp/pqp.zip instead of http://particletree.com/files/pqp/PhpQuickProfiler.zip ;)

  22. Lucas · 2 years ago

    Cool demo I really want to try but for me it says Undefined index: debugger_logs. And pls include README. Anyway, very clear PHP code.

  23. Shubham · 2 years ago

    Awesome stuff. Going into my PHP toolbox right now!

  24. Ryan Campbell · 2 years ago

    Updated newest copy to include README.

  25. Stuart Loxton · 2 years ago

    I’ve had a very similar system for debugging in browser; the one I use is more for debugging requests + responses. So has tabs for POST, GET, SESSION and COOKIE vars as well as database queries. However it looks a million times worse than PQP. Going to try and integrate it this weekend and also make some customisations, have a few small ideas for enhancements.

  26. Stuart Loxton · 2 years ago

    Decided to start making changes and thought I would share some of them: (url: http://demos.stuartloxton.com/pqp/)

    1) Removed height toggle button and instead PQP is resizable via jQuery UI - mouse to top of black box and a grey bar should appear, click and drag up and down. 2) Details now animates as well as remembering how tall PQP was. 3) In the log you can filter types of messages by toggling the large icons on the right. e.g. clicking logs will hide logs in the console. 4) Arrays inside of the console are formatted closer to firebugs, by default the array print_r is hidden, and instead a link is shown with a preview of the first _two_elements, click it and the whole print_r will display. 5) If details are hidden when you click a tab PQP opens instead of silently changing tabs but not showing the tab.

    Hope you don’t mind me destroying PQP and re-tweaking things, I’ve made sure to leave the PHP Quick Profiler logo in the bottom left.

  27. Ryan Campbell · 2 years ago

    Looking good, Stuart. We don’t mind at all — keep on improving it. I’ll probably be making a public project for the source, and will gradually improve on that. But your improvements are great and available for everyone now, so it’s definitely something other developers should look at. Your step 3) and 4) are my favorite, so I may have to borrow those ideas down the road.

  28. Chris Dary · 2 years ago

    It looks good, but it could use a bit more abstracting - I had to do quite a bit of finagling to get it to work in the default configuration with my application layout. (Specifically, using DOCUMENT_ROOT hosed my config. I just used dirname(dirname(FILE)) instead and included the CSS manually.)

    Also, you should maybe include an Interface that the DB class could Implement, that just includes $queryCount and $queries. It’d probably make it clearer what you need to work PQP.

    Also, I’d really like to know what license this is being released under! Creative Commons 2.5? (That’s what this site is.)

  29. Ryan Campbell · 2 years ago

    Great feedback, Chris. I hadn’t thought about an Interface for the DB class, but that would definitely be a more elegant way of handling it. Also, the code is released under Creative Commons Attribution 3.0 License.

  30. David Jones · 2 years ago

    To get started, I dropped your PQP folder in the top level of my site.

    When I visit the site (http://localhost:8888/pqp/) I get the following error messages.

    What do I need to do to resolve these errors??

    Are you planning a mailing list for people who use PQP, … to notify them of updates?

    Thanks!

    Notice: Undefined index: logCount in /Users/djones/Sites/MAMP/pqp/classes/Console.php on line 28 Notice: Undefined index: memoryCount in /Users/djones/Sites/MAMP/pqp/classes/Console.php on line 45 Notice: Undefined index: speedCount in /Users/djones/Sites/MAMP/pqp/classes/Console.php on line 74 Notice: Undefined index: errorCount in /Users/djones/Sites/MAMP/pqp/classes/Console.php on line 60

  31. Avaz Mano · 2 years ago

    Very cool, I was looking for something like this. Thanks!

  32. Gigel Plancton · 2 years ago

    PHP Quick Profiler is great, love the design and the simplicity! @David Jones: Those are notices, not errors, disable error reporting in your app if you don’t need it.

  33. Gaurav · 2 years ago

    I have been using firephp to debug my projects. I think this tools is very useful. Now i can use this for my future projects.

  34. Marc Gear · 2 years ago

    Surely it would be better to use a proper debugger/profiler (like Xdebug) than litter your code with these extraneous method calls.?

  35. Marc Gear · 2 years ago

    Everyone needs a hug.

  36. George Larson · 2 years ago

    Everyone DOES need a hug.

  37. Shahriat Hossain · 2 years ago

    Really great invention and helpful to make it out my project code optimization, Thanks for sharing this PQP.

  38. edson · 2 years ago

    how about a pre-integration with adodb classes?

  39. David Reuss · 2 years ago

    You should really put something like this on github, or any other social code hosting site. It’s pretty cool as is, the changes by stuart loxton makes it even better, and everybody will get the immediate benefit if the barrier to entry/change was really small.

    There’s also some specific code errors that should be worked out, for getting it to behave on there more strict setup. Specifically there’s a lot of strict warnings in there, calling methods statically that’s not declared static and such stuff.

    Making people involved in this by putting it up with full source/history freely available would make me want to hack on it and contribute back. Sending patches by email/other just doesn’t cut it these days :-)

  40. Ad Manager · 2 years ago

    Wow, this is visually attractive. If only the guys from Xdebug could incorporate this, at least the styling so integration is even simpler.

  41. Shawn · 2 years ago

    I’m assuming this was written for PHP4 because it throws more PHP5 strict warnings than Homer eats donuts. Sure is pretty though

  42. Shawn · 2 years ago

    Holy @#$%. It was DEFINITELY written for PHP4. $GLOBALS? Really? I’m a bit thrown off. I mean come on, GLOBALS? Make Console a singleton, all its methods are static anyway.

  43. Kevin Hale · 2 years ago

    Guys. Ryan explained the static calls and global variable usage in the article.

    “The static function call accepts any data type and is available as long as the PhpQuickProfiler.php class is included. We chose to implement this with a static call so that the class does not have to be instantiated before use. The downside to a static call is that we store the log history in a global php variable. Should you wish to avoid globals, the Console.php class could always hold the log as a member variable given that it is instantiated. But as is, the class just acts as a read and write wrapper around a global PHP variable.”

  44. mAritz · 2 years ago

    Great tool. Thank you very much. :) (veeeery nice work from Kevin on the design)

    However, I think you should really fix those nasty notices. It’s not that difficult/much work. (i fixed most of them in less then 5 minutes) Seeing as this tool is especialy usefull in development environments you should not tell anyone to just disable error reporting.

  45. Steven Surowiec · 2 years ago

    Ryan, I’m integrating this into a site I’m working on that’s using a custom MVC style setup and am finding a lot of little pieces that I am improving upon. With your permission (my emails on the comment so feel free to send me one) I’d like to toss a copy, with my changes, up on my Github account as I know a couple other people that have expressed an interest in doing the same.

  46. Matthaus Litteken · 2 years ago

    Adding some isset function calls to the source would also get ride of the notice (undefined index errors). When developing (when I would most use this), I leave the error reporting to include notices, as I find them helpful. Line 35 in PhpQuickProfiler.php and Lines 82-85 in Console.php were the ones that came up as undefined index immediately on the first run (and there were some more on the demo page). I can’t wait to give this a more thorough trying out. It looks awesome so far.

  47. Dan Fritcher · 2 years ago

    Great start - very clean. Very interested to see what Steven comes up with so it behaves a little better with MVC sites.

  48. Vladimir Carrer · 2 years ago

    Great job! I developed something similar but without graphical layout. It will be interesting to some how integrate CPU consumption(there is no direct PHP way to do this).

  49. Melvin Lee · 2 years ago

    I’m loving this tool right here. I’ve tweaked and did some hacking to work as a WordPress plugin: http://www.zy.sg/wp-phpquickprofiler/

  50. anonymous · 2 years ago

    You guys should try web grinder. its really good. Google it.

  51. Greg Saton · 2 years ago

    I’m trying to get this to work with Drupal, but I’m not sure where to plug in the code. Any hints?

  52. Tam Nguyen · 2 years ago

    That’s great. I use Firebug and Web Developer add-on for all times. Another choice ^_^

  53. Dan Morin · 2 years ago

    If anyone uses CodeIgniter, check out http://codeigniter.com/forums/viewthread/112572/ for a version adapted for CI.

  54. kristofer · 2 years ago

    umm.. xdebug anyone? why litter your code with extraneous methods when you can run it in an interactive debugger?

    http://www.xdebug.org/

  55. Eric Junker · 2 years ago

    Why not put this on github.com? That way it will be under source control and people can help make improvements. Also you should note that this requires PHP > 5.2 since memory_get_peak_usage() is only in > 5.2

  56. Eric Junker · 2 years ago

    Another similar project http://www.php-debug.com/www/

  57. Simon · 2 years ago

    Looks great!

  58. Michael · 2 years ago

    Very nice, integrated it in our social network. Nice work!

  59. Ryan LeFevre · 2 years ago

    Love the project and the design. I’ve been working on integrating it into my open-source forum project Osimo: http://getosimo.com/forums

    The forum system is still in a pretty heavy under-development phase so I just have PQP enabled by default. I added a simple mechanism though that will enable PQP only for certain IP addresses automatically.

    As others have mentioned above, I would love to see this put onto gethub or some similar site as I would like to contribute to the project.

  60. David Eads · 2 years ago

    I started a Drupal module. It still lacks query logging and I want a few more people to try it before I push it into Drupal’s CVS tree, but it is available in my personal Mercurial repository: http://hg.invisibleinstitute.com/drupal/pqp/

  61. Gordon · 2 years ago

    Firephp rocks. It shoots out any debugging stuff in the HTML headers for firebug to display. That way it’s guaranteed not to break your page (especially when doing ajax calls with xml or json) since the debugging isn’t in the result page!

    For those stuck with IE though, this is very nice. Awesome styling!

  62. Ryan · 2 years ago

    Very awesome job!

    I second the GitHub comments. Getting this out so that it can be improved would be great.

  63. Pat Collins · 2 years ago

    Guys, I am very impressed. I was able to download and integrate the Queries tab very quickly with an existing CakePHP project, and instantly see how much overhead I was dealing with. Brilliant.

    That said, I made a few adjustments to make it work in a CakePHP environment that I’ll share once I find an appropriate avenue for it.

  64. Vizor · 2 years ago

    Very cool! Russian description at http://vizor-it.net/2009/04/27/php-quick-profiler-analyzing-php-performance/

  65. caktux · 2 years ago

    I’ve created a wrapper module for Drupal, this is way too awesome :D Thanks guys!!! http://www.drupal.org/project/pqp

  66. Ed Hardy · 2 years ago

    Hey Guys!!

    Thanks for these very usefull information.

    Regards

  67. Khalid · 2 years ago

    Thanx

  68. Khalid · 2 years ago

    Thank you

  69. Ellery · 1 year ago

    Hi. Nice work. One suggestion: what do you think if the database layer is being implemented in PDO, so that postgresql, mysql, SQL server and sqlite can all be used the same profiler for testing purpose?

  70. Aish · 1 year ago

    This is an awesome post :)

    Thank you for providing the code and the how-to walk through. I came here through a google search and now I shall remain your frequent visitor! This is a great site.

  71. Meli · 1 year ago

    Everyone needs a hug.

  72. Maha · 1 year ago

    I loved the post

  73. Maha · 1 year ago

    Thanks for the lovely tutorial

  74. lcd televisies · 1 year ago

    Wow thanks. I am trying it now.

  75. SkyKnight · 1 year ago

    Very nice util - thx :-)

  76. New York Website Design · 1 year ago

    New York Website Design Company uses PHP Quick Profiler for coding projects.

    This premiere full-service New York Website Design company delivers web design and internet marketing SEO services. Contact New York Website Design Company for all custom website design and development needs in NYC and NY state.

  77. Richard Reyaz · 1 year ago

    Great post! Found this during a Google search while doing some research for an assignment for my Web Design and Development program from American Sentinel University (http://americansentinel.edu).

    I’ve bookmarked you and added you on Stumble and Delicious! Appreciate the helpful information, and will definitely be returning here again in the future!

  78. Aliester · 1 year ago

    Really nice work you have done,thank you for providing the code and the how-to walk through. I came here through a google search and now I shall remain your frequent visitor!

  79. Shapia web services · 1 year ago

    This posting gives out great information for the people like me, who aren’t having good experience on PHP. I am really happy that I am in the right place to enhance my PHP knowledge. I working in leading web design and Internet marketing services company, Bangalore

  80. Petr · 1 year ago

    Very nice idea! Do you plan further development of this cute app?

  81. Wenen · 1 year ago

    Thanks very much for this post. I really like the a 5 tabbed interface.

  82. Josh Moyers · 1 year ago

    Excellent, I’ve added this to my latest project… It’s making my try catch blocks with all these SOAP interactions so much nicer to debug. One thing that is useful for Soap based Exceptions is getting a bit more out of the Exception object, rather than just getLine() and getFile() etc, as its usually got quite a bit more information that is useful for debugging (ie, a specific error message from an EJB service for instance, specific parameters passed). I’ve modified my version and am happily using it. I wish I didn’t already have like 6 trillion unwrapped sql queries so I could implement the sql tab easily. Also, on the notices, you can just add definitions to the PhpQuickProfiler constructor and it solves that nag. This reminds me of the old Half Life console~

    Thanks!

  83. web design leeds · 1 year ago

    cheers for this! I liked the 5 tabbed interface too especially.

  84. Scott · 1 year ago

    Hmm, I’m getting the undefined index errors as well. Do I need to change a php.ini setting to fix this?

    Any help would be greatly appreciated!

  85. royal dragon · 1 year ago

    Hi Scott, I don’t have this problem. Maybe retry it?

  86. Disraeli · 1 year ago

    Everyone needs a hug.

  87. Aliester · 1 year ago

    I think you should really fix those nasty notices. It’s not that difficult/much work. (i fixed most of them in less then 5 minutes) Seeing as this tool is especialy usefull in development environments you should not tell anyone to just disable error reporting.

  88. Private Label Rights · 1 year ago

    I don’t have problem like this, all is fine.

  89. Marketing Templates · 1 year ago

    Thanks for the nice read!

  90. luke · 1 year ago

    link not working

  91. frank · 1 year ago

    Everyone needs a hug. google

  92. phpx · 1 year ago

    good work

  93. epc london · 1 year ago

    many thanks for this, peace out

  94. burlesque performer · 1 year ago

    Everyone needs a hug.

  95. Corsica · 1 year ago

    Perfect! thanks very much everybody!

  96. glexis · 1 year ago

    thakn you so much.perfect:)

  97. vancouver web design · 1 year ago

    Slick. Thanks for making this available!

  98. azlan sulaiman · 1 year ago

    how can i get this scrip comen…. cau u help me…

  99. jqueryin · 1 year ago

    I set this up fairly easily last night (all functionality) with my own personal framework. A few tweaks were necessary, mainly involving notices of unset log variables. You should really consider using isset() in a number of places. I also had a few issues with the stylesheet and query EXPLAIN statements. I had to add some rules for overflow:hidden and set a few widths explicitly as to not break the stylesheet.

    One of the biggest bugs that I noticed was the Query Profiler attempts to run EXPLAIN statements on non-select queries. This was easily remedied like so:

        function attemptToExplainQuery($query) {        if (strpos($query['sql'], 'SELECT') === 0) {            try {
                    $sql = 'EXPLAIN '.$query['sql'];
                    $rs = $this->db->get_row($sql, 0, 'ARRAY_A');
                }
                catch(Exception $e) {}
                if($rs) {
                    $query['explain'] = $rs;
                }        }
            return $query;
        }
    
  100. Chris · 1 year ago

    Hi,

    PQP has been great for helping me to diagnose some bottlenecks in my framework, thanks for releasing it! I’m not sure if you host the code anywhere for changes (e.g. github), but thought I’d post a quick modification I made. The code below will cause logSpeed() to log the time difference since the last logSpeed call. I’ll admit that I’ve not tested these extensively, but it seems to work in my app OK. Note that the first call to logSpeed() will always show a time-diff of 0 (zero).

    classes/Console.php

    public function logSpeed($name = 'Point in Time') { $now = PhpQuickProfiler::getMicroTime();

    if(isset($GLOBALS['debugger_logs']['lastSpeed']))
        $delta = $now - $GLOBALS['debugger_logs']['lastSpeed'];
    else
      $delta = 0;    $logItem = array(
            "data" => array(
        "cumulative" => $now,
        "delta" => $delta
      ),
            "type" => 'speed',
            "name" => $name
        );    $GLOBALS['debugger_logs']['console'][] = $logItem;
        $GLOBALS['debugger_logs']['speedCount'] += 1;
        $GLOBALS['debugger_logs']['lastSpeed'] = $now;
    }
    

    and to show the delta/cumulative times:

    classes/PhpQuickProfiler.php

    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') { $times = $this->getReadableTime(($log['data']['delta']) * 1000) . " / " . $this->getReadableTime(($log['data']['cumulative'] - $this->startTime) * 1000); $logs['console'][$key]['data'] = $times; } } } $this->output['logs'] = $logs; }

    Thanks! Chris

  101. Chris · 1 year ago

    Sorry, I messed up the code tags in my previous comment. Appreciate it if you could edit the comment to wrap the code correctly.

    Thanks :)

  102. Christopher · 1 year ago

    Brilliant, thanks very much!

  103. Christopher · 1 year ago

    Cool, thanks!

  104. Patrick · 1 year ago

    Hi Ryan, Great project. Hey, I found a few bugs that you may want to fix. I tend to make sure my stuff works cleanly all the way down to strict error checking and pqp threw me a list. In Console.php you forgot to make most of the methods static. Also the final method does not properly initialize the debugger_logs global array. Here’s what it should be to eliminate all notices in strict mode: public static function getLogs() { if(!isset($GLOBALS[‘debugger_logs’][‘console’])) $GLOBALS[‘debugger_logs’][‘console’] = array(); if(!isset($GLOBALS[‘debugger_logs’][‘memoryCount’])) $GLOBALS[‘debugger_logs’][‘memoryCount’] = 0; if(!isset($GLOBALS[‘debugger_logs’][‘logCount’])) $GLOBALS[‘debugger_logs’][‘logCount’] = 0; if(!isset($GLOBALS[‘debugger_logs’][‘speedCount’])) $GLOBALS[‘debugger_logs’][‘speedCount’] = 0; if(!isset($GLOBALS[‘debugger_logs’][‘errorCount’])) $GLOBALS[‘debugger_logs’][‘errorCount’] = 0; return $GLOBALS[‘debugger_logs’]; }

  105. Juan M · 1 year ago

    Currently, my active debug like this: // ************************** // // Debug Mode if (isset($_POST[‘debug’]) && $_POST[‘debug’] != $game_config[‘debug’]) { update_config(‘debug’, $_POST[‘debug’]); $game_config[‘debug’] = $_POST[‘debug’]; } // ************************* // And can not start your debug my site.

  106. Uzlain · 1 year ago

    Hey,

    Thanks that ! it works fine. Have you planed any way to log Ajax request ?

    Thankies

  107. ntiremedia · 1 year ago

    tnx frnd its great info ….

  108. Michael · 1 year ago

    Hi Ryan - I am stress testing my Php/MySql website using the free Microsoft Stress Analysis tool. I am running tests along the line of - simulate hitting this sequence of actions on these pages by so many users per second for so many minutes or hours. I need to accumulate statistics like what your library gathers, but for multiple sessions over a period of time. Can the pqp library accommodate this, or is there a way to tweak it, or do you have any alternative suggestions? From what I can tell, pqp will accumulate statistics only for a single hit of the page - is this accurate?

    Keep up the great work!

    -Michael

  109. KumbiaPHP Framework · 1 year ago

    Please, could you say which license have php quick profiler. Is for know if we can include in our php framework KumbiaPHP directaly. Or if we will create it like a separate download. Tanks.

  110. Richard · 1 year ago

    It’s going a bit off topic (but given that the last few comments are spam I figure its OK) but I was wondering if you guys actually use MAMP as a local development server. It comes up in a few of your older posts, but I wonder if its actually proved useful for local development or if you’ve move to using OSX’s built in Apache, or a virtualised server. Thanks!

  111. Christopher Roberts · 1 year ago

    It worked very well, thanks :)

  112. Vernon Jefferson · 1 year ago

    worked like a charm. thx

  113. ParkSmart · 1 year ago

    This is working very good!

  114. Jhonny Makis · 1 year ago

    Parabéns pelo excelente trabalho. =)

  115. Istanbul · 1 year ago

    Why not put this on github.com? That way it will be under source control and people can help make improvements. Also you should note that this requires PHP > 5.2 since memory_get_peak_usage() is only in > 5.2

  116. Aana Parker · 1 year ago

    I am Aana Parker, i work in a website designing company and I have found this very useful. It is working gr8. thanx.

  117. Steven Surowiec · 1 year ago

    Istanbul - I’ve put a fork of this up on github under the name PHP-Profiler (still working on a better one) if you’d like to contribute. I’ve done a lot of code clean up and have begun extending the feature set as well.

  118. Dusseldorf Trein · 1 year ago

    Hi Aana. Great site has your company. Do they also have clients abroad?

  119. web page designer · 1 year ago

    This worked perfect for me, much appreciated!

  120. Belgie trein · 1 year ago

    I worked also for me. Thanks for the post.

  121. Bert · 1 year ago

    Great information and it exactly worked for me as well. Normally I’m quite skeptical but it proved to be useful!

  122. Corporate Web Design · 1 year ago

    This works really well, thanks.

  123. Marty Mapes · 1 year ago

    I found slow queries that didn’t look like slow queries thanks to the handy interface. Doubled the speed of my biggest pages on Movie Habit. Good work!

  124. Wim · 1 year ago

    Good work, thanks!

  125. Birthday Flowers · 1 year ago

    I’m impressed. All that your work is unbelievable. Good work, I have to admit.

  126. SimonSimCity · 1 year ago

    Hi, All

    This is a great tool !!!

    The only line I’ve changed is inside the MySqlDatabase.php If your Query was incorrect you’ll only get the message “Could not execute query.” but why don’t add the whole errormessage f.e. by using the PHP-function mysql_error()

    Here is an example for line 68

    throw new Exception('Could not execute query.' . "\nerror-message: " . mysql_error());
    
  127. Emma Smyth · 1 year ago

    This also worked perfect for me, much appreciated and thanks :)

  128. Hypotheken vergelijken · 1 year ago

    Thanx, this works really well!

  129. Shawn · 1 year ago

    Had to make a few edits to get it to work on my server.

    But, had a question for you, if I were to include the profiler script through out different classes, how would I be able to make it pass through them all. Have several classes, each with their own functions which are called by another included file. I would love to be able to have it all out put on the screen. So when I load 3-4 classes with db queries in them, it can all be displayed.

    Thoughts anyone?

  130. Peter · 1 year ago

    Getting the debugger to report database information is the hardest part. Yeah but it is working now! Thanks.

  131. Nate Smith · 1 year ago

    This is fantastic.

  132. larkin · 1 year ago

    Thank god at last I have got a real site that would help me. Thanks for this informations.

  133. ylan · 1 year ago

    Hello,

    May someone tell me what does it mean please? Strict Standards: Non-static method PhpQuickProfiler::getMicroTime() should not be called statically in /var/www/html/http/a2billing/common/lib/admin.defines.php on line 6

    Thanks in advnace

  134. Website Design KC · 1 year ago

    This is great, exactly what i was looking for. I work for a [url=http://www.theturngroup.com]Website Design in KC[url/] company and am always looking for useful information.