Hi there,
Is it possible to make the declare(ticks=1) statement apply to *all*
functions executed in a php script, regardless of scope?
I wish to write a profiler script to basically dump all the function call
times through the execution of a script. So far, I can only get it to work
for functions called via global scope.
My code calls only one function from the global scope, and then a whole lot
of functions in classes are invoked. The tick function is only invoked once
from calling this one global function.
Here is my code:
<?php
declare(ticks = 1);
/**
* Profiler
*
* @version SVN: $Id$
* @author Scott McNaught
*/
class Profiler
{
protected $m_arrProfileData = array();
protected $m_strCurrentFunction = null;
protected $m_iLastTime = null;
/**
* Begins profiling
*/
public function start()
{
$this->m_iLastTime = time();
}
/**
* Finishes profiling and dumps the results
*/
public function end()
{
var_dump($this->m_arrProfileData);
$this->m_arrProfileData = array();
$this->m_strCurrentFunction = null;
}
public function tick()
{
$arrBacktrace = debug_backtrace();
if (!isset($arrBacktrace[1]))
{
return;
}
$strFunction = $arrBacktrace[1]['function'];
if (isset($arrBacktrace[1]['class']))
{
$strFunction = $arrBacktrace[1]['class'] . '::' .
$strFunction;
}
$iTime = microtime(true);
if (!isset($this->m_arrProfileData[$strFunction]))
{
$this->m_arrProfileData[$strFunction] = $iTime;
}
$this->m_arrProfileData[$strFunction] += $iTime -
$this->m_iLastTime;
$this->m_iLastTime = $iTime;
$this->m_strCurrentFunction = $strFunction;
}
}
$pProfiler = new Profiler();
register_tick_function($pProfiler, 'tick'), true);
?>
Then from index.php.
<?php
if(isset($_GET['profile']))
{
include('profiler.inc.php');
}
function execute()
{
$pClass = new SomeClass();
$pClass->someFunction();
}
execute(); // TICK IS CALLED FROM EXECUTING THIS
?>
So a tick is made from calling execute() from global scope, and that is it.
I want it to tick when someFunction() is called.
I would really appreciate any help that anyone can give me with this as I
have struggled with it for a while, and there is not much documentation
about this anywhere.
This could potentially benefit a lot of people if engineered right. I am
trying to make a profiler include file which will be able to be used with
one line of file.
This will allow people to:
. Get quick profiler results on demand by adding something to the
query string - eg - ?profile=1
. Get profile results for novices without having to mess around
installing php binaries such as APD / zend debugger etc
. Profile on demand on production servers without having to install
a resource intensive debugging module
Any help greatly appreciated.
Thanks,
Scott McNaught