Forma mais simples de analisar um programa de PHP

Qual é a maneira mais fácil de traçar um script PHP?

Eu adoraria colocar algo que me mostre uma descarga de todas as chamadas de funções e quanto tempo elas demoraram, mas também não me importo de colocar algo em torno de funções específicas.

tentei experimentar com a função microtime :

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);
Mas isso às vezes dá-me resultados negativos. Além disso, dá muito trabalho espalhar isso pelo meu código.

 263
Author: Mark Biek, 2008-08-22

12 answers

A extensão dePECL APD é utilizada do seguinte modo:

<?php
apd_set_pprof_trace();

//rest of the script
?>

Depois, analisar o ficheiro gerado usando pprofp.

Exemplo de saída:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace
 102
Author: Vincent, 2012-12-22 00:46:49

Você quer xdebug Eu acho. Instalá-lo no servidor, ative-a, bomba de saída através kcachegrind (para linux) ou wincachegrind (para windows) e ele vai mostrar-lhe alguns bonitos gráficos que detalham os intervalos exatos, contagens e o uso de memória (mas você vai precisar de outra extensão para que).

É o máximo, a sério.
 251
Author: mercutio, 2013-08-28 09:20:36

Não são necessárias extensões, basta usar estas duas funções para um perfil simples.

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

Aqui está um exemplo, chamando prof_flag () com uma descrição em cada checkpoint, e prof_print () no final:

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

A saída parece-se com esta:

Início
0.004303
Ligue para DB
0.003518
Executar a consulta
0.000308
Recuperar dados
0.000009
Fechar DB
0.000049
Feito

 76
Author: TimH, 2015-09-18 20:45:49

Se subtrair microtimes lhe der resultados negativos, tente usar a função com o argumento true (microtime(true)). Com true, a função devolve um 'float' em vez de um 'string' (como acontece se for chamado sem argumentos).

 23
Author: luka, 2013-08-06 14:22:15
Sinceramente, vou argumentar que usar a NewRelic para traçar perfis é o melhor. É uma extensão PHP que não parece abrandar o tempo de execução e eles fazem a monitorização por ti, permitindo um exercício decente. Na versão cara eles permitem um exercício pesado para baixo (mas nós não podemos pagar o seu modelo de preços). Ainda assim, mesmo com o plano livre / padrão, é óbvio e simples onde está a maioria das frutas baixas Penduradas. Também gosto que te dê uma ideia sobre DB. interações também.

screenshot of one of the interfaces when profiling

 21
Author: zeroasterisk, 2013-12-19 02:13:57

cruza a minha referência da documentação beta que está a ficar offline.

Análise de perfis com XDebug

Está disponível uma extensão para o PHP chamada Xdebug para ajudar em a traçar o perfil das aplicações do PHP, assim como a depuração em tempo de execução. Ao executar o profiler, a saída é escrita para um arquivo em um formato binário chamado "cachegrind". As aplicações estão disponíveis em cada plataforma para analisar esses arquivos. não são necessárias alterações ao código de aplicação para execute este perfil.

Para activar o perfil, instalar a extensão e ajustar o php.configurações ini. Algumas distribuições Linux vêm com pacotes padrão(por exemplo, pacote Ubuntu php-xdebug). No nosso exemplo, executaremos o perfil opcionalmente com base num parâmetro de pedido. Isso nos permite manter as configurações estáticas e ligar o profiler apenas quando necessário.

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

Em seguida, use um cliente web para fazer um pedido ao URL da sua aplicação que deseja traçar, por exemplo

http://example.com/article/1?XDEBUG_PROFILE=1

Como a página processes it will write to a file with a name similar to

/tmp/cachegrind.out.12345

Por padrão, o número no nome do ficheiro é o id do processo que o escreveu. Isto é configurável com a configuração xdebug.profiler_output_name.

Note que ele irá escrever um arquivo para cada pedido / processo de PHP que é executado. Assim, por exemplo, se você deseja analisar um post de formulário, um perfil será escrito para o pedido GET para exibir o formulário HTML. O parâmetro XDEBUG_ profile terá de ser passado para a publicação subsequente pedido para analisar o segundo pedido que processa o formulário. Portanto, quando o perfil é às vezes mais fácil de executar curl para postar um formulário diretamente.

Analisando a saída

Uma vez escrita a 'cache' de perfis pode ser lida por uma aplicação como KCachegrind ou Webgrind . PHPStorm, um IDE PHP popular, também pode mostrar estes dados de análise .

KCachegrind

O KCachegrind, por exemplo, irá mostrar informações incluindo:

  • funções executadas
  • Tempo de chamada, tanto em si como inclusivo de chamadas de funções subsequentes
  • Número de vezes que cada função é chamada
  • gráficos de chamadas
  • ligações ao código-fonte

O que procurar

É óbvio que a sintonização de desempenho é muito específica dos casos de utilização de cada aplicação. Em geral, é bom olhar para:

    Chamadas repetidas para a mesma função que não esperava ver. Para funções que processam e consulta dados estes podem ser oportunidades principais para o seu aplicativo para cache.
  • funções de execução lenta. Onde é que a aplicação passa a maior parte do seu tempo? o melhor pagamento em ajuste de desempenho está focando nas partes da aplicação que consomem mais tempo.

Nota : o Xdebug, e em particular as suas características de perfil, são muito intensivos em recursos e atrasam a execução do PHP. Recomenda-se que estes não sejam executados numa produção ambiente do servidor.

 16
Author: Matt S, 2018-09-19 13:06:59

PECL XHPROF também parece interessante. Tem interface HTML clicável para ver relatórios e documentação bastante simples . Ainda não o testei.

 10
Author: Josef Sábl, 2011-06-23 11:26:12
Gosto de usar o phpDebug para traçar perfis. http://phpdebug.sourceforge.net/www/index.html

Ele emite toda a utilização de tempo / memória para qualquer SQL usado, bem como todos os arquivos incluídos. Obviamente, funciona melhor em código que é abstraído.

Para funções e perfis de classe vou usar microtime() + get_memory_usage() + get_peak_memory_usage().

 8
Author: Eric Lamb, 2012-10-04 19:15:16
O perfil do pobre homem não requer extensões. Suporta perfis aninhados e percentagem do total:
function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

Exemplo:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

Rendimentos:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]
 7
Author: bishop, 2016-09-07 20:36:48

Eu defiantly dariaBlackFire uma tentativa.

Existe esta virtualBox que juntei usando o puphpet , para testar diferentes frameworks do php que coms com o BlackFire, sinta-se à vontade para bifurcar e/ou distribuir, se necessário :)

Https://github.com/webit4me/PHPFrameworks

 5
Author: Ali, 2015-09-29 21:04:20

Para o benchmarking, como no seu exemplo, eu uso o pacotepear Benchmark . Você coloca marcadores para medir. A classe também fornece alguns ajudantes de apresentação, ou você pode processar os dados como quiser.

Tenho-o embrulhado noutra classe com um método de destruição. Quando um script sai, a saída é registrada através de log4php para syslog, então eu tenho um monte de dados de desempenho para trabalhar.
 4
Author: Gary Richardson, 2008-08-22 15:43:20

O XDebug não é estável e nem sempre está disponível para uma versão específica do php. Por exemplo, em alguns servidores que ainda executo o php-5.1.6, -- é o que vem com o RedHat RHEL5( e o btw ainda recebe atualizações para todas as questões importantes), e o xdebug recente nem sequer compila com este php. Por isso acabei por mudar para o depurador DBG A sua análise comparativa do php fornece o tempo para funções, métodos, módulos e linhas pares.

 2
Author: user2221743, 2013-04-04 07:48:58