Obter o nome da função de chamada em PHP?

135

Existe uma função PHP para descobrir o nome da função chamadora em uma determinada função?

miken32
fonte
Você deve usar o Xdebug. Veja minha resposta neste post: stackoverflow.com/questions/1513069/…
svassr 29/03/2012
13
O Xdebug não é categoricamente apenas uma função PHP, que era a solicitação original. Se você quiser, por exemplo, usar o nome da função de chamada na lógica PHP posterior e não instalar o XDebug nos servidores de produção, precisará de uma função PHP.
JP

Respostas:

198

Veja debug_backtrace - isso pode rastrear sua pilha de chamadas até o topo.

Veja como você chamaria o chamador:

$trace = debug_backtrace();
$caller = $trace[1];

echo "Called by {$caller['function']}";
if (isset($caller['class']))
    echo " in {$caller['class']}";
Paul Dixon
fonte
59
Parece-me que isso imprime o nome da função de chamada. Use list(, $caller) = debug_backtrace(false);para obter o chamador, falsepara desempenho ;-) (php5.3)
Znarkus
Muitas soluções vistas na Web obtêm o segundo elemento da matriz de backtrace para obter o chamador da instância: podemos ter tanta certeza disso? O segundo elemento é sempre o que estamos procurando? Eu pensei que um __construct () que inclui dentro de outra chamada, como parent :: __ construct (), poderia mudar de outra posição que o chamador real (ainda não tentou).
Emanuele Del Grande
1
Tentei verificar a ordem dos chamadores retornados durante o uso de um ReflectionClass e, obviamente, altera a posição do método "real" do chamador, que é visível na interface do usuário, para que nenhuma suposição sobre a posição do backtrace possa ser feita.
Emanuele Del Grande
4
o deslocamento da matriz removerá o primeiro elemento e retornará o elemento removido. A matriz original será modificada e isso deve dar o resultado pretendidoecho 'called by '.$trace[0]['function']
GoodSp33d
21
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];para obter o nome do chamador com melhor desempenho.
Ahuigo 08/04
17

O Xdebug fornece algumas funções interessantes.

<?php
  Class MyClass
  {
    function __construct(){
        $this->callee();
    }
    function callee() {
        echo sprintf("callee() called @ %s: %s from %s::%s",
            xdebug_call_file(),
            xdebug_call_line(),
            xdebug_call_class(),
            xdebug_call_function()
        );
    }
  }
  $rollDebug = new MyClass();
?>

retornará rastreio

callee() called @ /var/www/xd.php: 16 from MyClass::__construct

Para instalar o Xdebug no ubuntu, a melhor maneira é

sudo aptitude install php5-xdebug

Você pode precisar instalar o php5-dev primeiro

sudo aptitude install php5-dev

mais informações

svassr
fonte
15

É muito tarde, mas gostaria de compartilhar a função que fornecerá o nome da função a partir da qual a função atual é chamada.

public function getCallingFunctionName($completeTrace=false)
    {
        $trace=debug_backtrace();
        if($completeTrace)
        {
            $str = '';
            foreach($trace as $caller)
            {
                $str .= " -- Called by {$caller['function']}";
                if (isset($caller['class']))
                    $str .= " From Class {$caller['class']}";
            }
        }
        else
        {
            $caller=$trace[2];
            $str = "Called by {$caller['function']}";
            if (isset($caller['class']))
                $str .= " From Class {$caller['class']}";
        }
        return $str;
    }

Espero que isso seja útil.

ZOPE MANISH
fonte
1
Você é bem-vindo David !!! Também estou usando isso para fins de depuração no meu projeto :)
MANISH ZOPE
O modo "rastreamento completo" é muito útil. Obrigado por compartilhar.
Leopoldo Sanczyk 16/11/19
15

debug_backtrace() fornece detalhes de parâmetros, chamadas de função / método na pilha de chamadas atual.

CMS
fonte
9
echo debug_backtrace()[1]['function'];

Funciona desde o PHP 5.4 .

Ou otimizado (por exemplo, para casos de uso sem depuração):

echo debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];

O primeiro argumento impede o preenchimento de argumentos de função não utilizados, o segundo limita o rastreamento a dois níveis (precisamos do segundo).

flori
fonte
7

Feito isso e usando isso sozinho

/**
 * Gets the caller of the function where this function is called from
 * @param string what to return? (Leave empty to get all, or specify: "class", "function", "line", "class", etc.) - options see: http://php.net/manual/en/function.debug-backtrace.php
 */
function getCaller($what = NULL)
{
    $trace = debug_backtrace();
    $previousCall = $trace[2]; // 0 is this call, 1 is call in previous function, 2 is caller of that function

    if(isset($what))
    {
        return $previousCall[$what];
    }
    else
    {
        return $previousCall;
    }   
}
Paul Gobée
fonte
3

Eu só queria afirmar que o caminho de flori não funcionará como uma função, pois sempre retornará o nome da função chamada em vez do chamador, mas não tenho reputação de comentar. Fiz uma função muito simples com base na resposta de flori que funciona bem no meu caso:

class basicFunctions{

    public function getCallerFunction(){
        return debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
    }

}

EXEMPLO:

function a($authorisedFunctionsList = array("b")){
    $ref = new basicFunctions;
    $caller = $ref->getCallerFunction();

    if(in_array($caller,$authorisedFunctionsList)):
        echo "Welcome!";
        return true;
    else:
        echo "Unauthorised caller!";
        return false; 
    endif;
}

function b(){
    $executionContinues = $this->a();
    $executionContinues or exit;

    //Do something else..
}
lrd
fonte
2

Você pode extrair essas informações da matriz retornada por debug_backtrace

Richard Turner
fonte
2

Este funcionou melhor para mim: var_dump(debug_backtrace());

Gershon Herczeg
fonte
1

Isso deve funcionar:

$caller = next(debug_backtrace())['function'];
kenorb
fonte
0

Isso fará muito bem:


// Outputs an easy to read call trace
// Credit: https://www.php.net/manual/en/function.debug-backtrace.php#112238
// Gist: https://gist.github.com/UVLabs/692e542d3b53e079d36bc53b4ea20a4b

Class MyClass{

public function generateCallTrace()
{
    $e = new Exception();
    $trace = explode("\n", $e->getTraceAsString());
    // reverse array to make steps line up chronologically
    $trace = array_reverse($trace);
    array_shift($trace); // remove {main}
    array_pop($trace); // remove call to this method
    $length = count($trace);
    $result = array();
   
    for ($i = 0; $i < $length; $i++)
    {
        $result[] = ($i + 1)  . ')' . substr($trace[$i], strpos($trace[$i], ' ')); // replace '#someNum' with '$i)', set the right ordering
    }
   
    return "\t" . implode("\n\t", $result);
}

}

// call function where needed to output call trace

/**
Example output:
1) /var/www/test/test.php(15): SomeClass->__construct()
2) /var/www/test/SomeClass.class.php(36): SomeClass->callSomething()
**/```
Uriahs Victor
fonte