Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Plugin Name: Instrument Hooks for WordPress
Description: Instruments Hooks for a Page. Outputs during the Shutdown Hook.
Version: 0.1
Author: Mike Schinkel
Author URI:
if (isset($_GET['instrument']) && $_GET['instrument']=='hooks') {
function instrument_hooks() {
global $wpdb;
$hooks = $wpdb->get_results("SELECT * FROM wp_hook_list ORDER BY first_call");
$html = array();
$html[] = '<style>#instrumented-hook-list table,#instrumented-hook-list th,#instrumented-hook-list td {border:1px solid gray;padding:2px 5px;}</style>
<div align="center" id="instrumented-hook-list">
<th>First Call</th>
<th>Hook Name</th>
<th>Hook Type</th>
<th>Arg Count</th>
<th>Called By</th>
<th>Line #</th>
<th>File Name</th>
foreach($hooks as $hook) {
$html[] = "<tr>
$html[] = '</table></div>';
echo implode("\n",$html);
function record_hook_usage($hook){
global $wpdb;
static $in_hook = false;
static $first_call = 1;
static $doc_root;
$callstack = debug_backtrace();
if (!$in_hook) {
$in_hook = true;
if ($first_call==1) {
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$results = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wp_hook_list'");
if (count($results)==1) {
$wpdb->query("TRUNCATE TABLE wp_hook_list");
} else {
$wpdb->query("CREATE TABLE wp_hook_list (
called_by varchar(96) NOT NULL,
hook_name varchar(96) NOT NULL,
hook_type varchar(15) NOT NULL,
first_call int(11) NOT NULL,
arg_count tinyint(4) NOT NULL,
file_name varchar(128) NOT NULL,
line_num smallint NOT NULL,
PRIMARY KEY (first_call,hook_name))"
$args = func_get_args();
$arg_count = count($args)-1;
$hook_type = str_replace('do_','',
$file_name = addslashes(str_replace($doc_root,'',$callstack[3]['file']));
$line_num = $callstack[3]['line'];
$called_by = $callstack[4]['function'];
$wpdb->query("INSERT wp_hook_list
VALUES ($first_call,'$called_by()','$hook','$hook_type',$arg_count,'$file_name',$line_num)");
$in_hook = false;

Just tested this. Looks good. A small problem on windows - the file names do not escape backslashes so the path runs all together (cwampwww...)


Send a patch?

I am not setup for that right now. Sorry. So, just a bug report for now.


Can you explain the solution? I'm not sure what you are suggesting.

Oh, sorry I wasn't clear.
Basically, when the instrumentation table is displayed it, the file name does not take into account the fact that Windows file names use backslashes.
So, if the file path is: C:\Wamp\www\network, it will show up as C:wampwww[\n]etwork, where [\n] is now new line.

I think changing line 77 to use addslashes does the trick:
$file_name = addslashes(str_replace($doc_root,'',$callstack[3]['file']));


Perfect, thanks! I've edited. Can you confirm it works for you?

Seems to work fine. Thank you.

GeertDD commented Nov 19, 2011

You should do an isset or empty check for $_GET['instrument'] to prevent undefined variable errors.


@GeertDD - Sure, done.

perfect just what im looking for...

made small customisation where i could filter which hook type i need to view


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment