Как найти список функций, выполняемых для создания страницы? - PullRequest
3 голосов
/ 07 ноября 2010

Я хочу список всех функций, выполняемых до определенной точки в коде, как-то вроде debug_backtrace (), но включающий функции не в том потоке, который приводит к тому, где вызывается debug_backtrace () например:

a();

function a() { 
 b();     
 c(); 
 d(); 
}

function b() { }
function c() { }
function d() { print all_trace(); }

будет производить:

a(), b(), c(), d()

а не

a(), d()

как debug_backtrace () будет

Ответы [ 3 ]

3 голосов
/ 07 ноября 2010
1 голос
/ 07 ноября 2010

Вы можете установить обработчик tick , и на каждом тике использовать debug_backtrace, чтобы найти функцию, в которой вы находитесь, и добавить ее в список.Это снизит производительность, но даст список, который вы хотите.

$functions_called=array();


function tick_handler()
{
    $trace=debug_backtrace();

    //we're in tick_handler, let's eat that
    array_shift($trace);

    //if we're in a function, log it!
    if (!empty($trace))
    {
        $function=$trace[0]['function'];

        //log function - lets just remember it was called
        global $functions_called;
        $functions_called[$function]=1;
    }
}

//install our tick handler...
declare(ticks=1);
register_tick_function('tick_handler');

Вот как вы получите вывод, который вы укажете из этого:

function all_trace()
{
     global $functions_called;
     $output='';
     $separator='';
     foreach($functions_called as $func=>$dummy)
     {
          $output.=$separator.$func.'()';
          $separator=', ';
     }
     return $output;
}

Довольно неприятно - как и другиепредложить, лучше использовать такие инструменты, как xdebug , предназначенные для работы, если вы можете ...

0 голосов
/ 13 сентября 2012

не требуется Xdebug или dbg.so на сервере, верните более подробное сообщение, основанное на решении Пола Диксона:

diyism_trace.php:

<code><?
define(TRACES_MODE, 'TEXTAREA');//'TEXTAREA' or 'FIREPHP' or 'TMPLOG'
$GLOBALS['traces.pre']=array();
function my_array_diff($arr1, $arr2)
         {foreach ($arr1 as $k=>$v)
                  {if (in_array($v, $arr2, true))
                      {unset($arr1[$k]);
                      }
                  }
          return $arr1;
         }
function my_var_export($var, $is_str=false)
         {$rtn=preg_replace(array('/Array\s+\(/', '/\[(\d+)\] => (.*)\n/', '/\[([^\d].*)\] => (.*)\n/'), array('array (', '\1 => \'\2\''."\n", '\'\1\' => \'\2\''."\n"), substr(print_r($var, true), 0, -1));
          $rtn=strtr($rtn, array("=> 'array ('"=>'=> array ('));
          $rtn=strtr($rtn, array(")\n\n"=>")\n"));
          $rtn=strtr($rtn, array("'\n"=>"',\n", ")\n"=>"),\n"));
          $rtn=preg_replace(array('/\n +/e'), array('strtr(\'\0\', array(\'    \'=>\'  \'))'), $rtn);
          $rtn=strtr($rtn, array(" Object',"=>" Object'<-"));
          if ($is_str)
             {return $rtn;
             }
          else
              {echo $rtn;
              }
         }
function tick_handler()
         {$tmp=debug_backtrace();
          $trace=my_array_diff($tmp, $GLOBALS['traces.pre']);
          //echo '<pre>';var_export($trace);echo '
'; echo'
'; // для отладки diyism_trace.php $ След = array_values ​​($ трассировки); $ GLOBALS [ 'traces.pre'] = $ TMP; $ Весело = @ $ TMP [1] [ 'класс'] @ $ TMP [1] [ 'типа'] @ $ TMP [1] [ 'функция'].. if (count ($ trace)> 0 && $ trace [0] ['file']. '/'. $ fun! == @ $ GLOBALS ['traces'] [count ($ GLOBALS ['traces']) - 1] ['key']) // фильтровать пустой массив и переставлять array_values ​​(), потому что некоторые строки будут вызывать два тиковых события на строку, например: 1. последняя строка - это "некоторый код; квест-метка>" 2.error_reporting (. .. {for ($ i = count ($ trace) -1; $ i> = 0; - $ i) {$ Fun1 = @ $ TMP [$ + 1] [ 'класс'] @ $ TMP [$ + 1] [ 'тип'] @ $ TMP [$ + 1] [ 'функция']..; .. $ Fun2 = $ трассировать [$ я] [ 'класс'] $ след [$ я] [ 'тип'] $ след [$ я] [ 'функция']; $ GLOBALS [ 'следы'] [] = $ tmp_fb = array_merge массив 'ключ' ((=> $ след [$ я] [ 'файл']. '/'. $ Fun1), $ Прослеживать [$ я], массив ('function' => strtr ($ fun2, array ('tick_handler' => 'CONTINUE')), 'in_function' => $ fun1) ); TRACES_MODE === 'FIREPHP'? Fb (trace_output ($ tmp_fb), 'diyism_trace:'. ++ $ GLOBALS ['diyism_trace_no']): ''; } } } функция trace_output ($ trace) {$ trace ['in_function'] = strtr (@ $ trace ['in_function'], массив ('require' => '', 'require_once' => '', 'include' => '', 'include_once' = > '')); $ trace ['args'] = $ trace ['args']? strtr (preg_replace (array ('/ \ n + /'), array (''), preg_replace (array ('/ \ n \ d + => /) '), массив (' '), substr (my_var_export ($ trace [' args '], true), 7, -3))), массив ("\ r" =>' \ r ', "\ n" = > '\ п')): ''; return $ trace ['file']. ($ trace ['in_function']? '/'.$ trace [' in_function '].' () ':' ').' / '. $ trace [' line '] . ':'. $ trace ['function']. '('. $ trace ['args']. ')'; } функция traces_output () {$ request_id = base_convert (time (). substr (microtime (), 2,6) .mt_rand (), 10, 36); TRACES_MODE === 'TEXTAREA' ? (печать ''): ''; } register_tick_function ( 'tick_handler'); (TRACES_MODE === 'TEXTAREA' || TRACES_MODE === 'TMPLOG')? Register_shutdown_function ('traces_output'): ''; ?>

test.php:

<?
declare(ticks=1);
require 'diyism_trace.php';
a('a', array('hello'));
1+2;
b();
function a()
         {$d=1;
          b();
          $d=2;
          cls::c('cccc'); 
          $d=4;
          d(); 
          $d=5;
         }

function b()
         {1+1;
          d();
         }
class cls
      {static function c()
              {1+1;
              }
      }
function d()
         {1+1;
         }
?>

выход:

/var/www/test/test.php/3: CONTINUE()
/var/www/test/test.php/4: a('a',array (0 => 'hello',))
/var/www/test/test.php/a()/8: CONTINUE()
/var/www/test/test.php/a()/9: b()
/var/www/test/test.php/b()/18: CONTINUE()
/var/www/test/test.php/b()/19: d()
/var/www/test/test.php/d()/27: CONTINUE()
/var/www/test/test.php/b()/19: CONTINUE()
/var/www/test/test.php/a()/9: CONTINUE()
/var/www/test/test.php/a()/11: c('cccc')
/var/www/test/test.php/c()/23: CONTINUE()
/var/www/test/test.php/a()/11: CONTINUE()
/var/www/test/test.php/a()/13: d()
/var/www/test/test.php/d()/27: CONTINUE()
/var/www/test/test.php/a()/13: CONTINUE()
/var/www/test/test.php/4: CONTINUE()
/var/www/test/test.php/6: b()
/var/www/test/test.php/b()/18: CONTINUE()
/var/www/test/test.php/b()/19: d()
/var/www/test/test.php/d()/27: CONTINUE()
/var/www/test/test.php/b()/19: CONTINUE()
/var/www/test/test.php/6: CONTINUE()
...