Ottieni il nome della funzione chiamante in PHP?


135

Esiste una funzione PHP per scoprire il nome della funzione chiamante in una determinata funzione?


Dovresti usare Xdebug. Vedere la mia risposta in questo post: stackoverflow.com/questions/1513069/...
svassr

13
Xdebug non è categoricamente una funzione PHP, che era la richiesta originale. Se ad esempio si desidera utilizzare il nome della funzione chiamante nella logica PHP successiva e non installare XDebug sui server di produzione, è necessaria una funzione PHP.
JP,

Risposte:


198

Vedi debug_backtrace : questo può tracciare il tuo stack di chiamate fino in cima.

Ecco come otterresti il ​​tuo chiamante:

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

echo "Called by {$caller['function']}";
if (isset($caller['class']))
    echo " in {$caller['class']}";

59
Mi sembra che questo stampa il nome della funzione di chiamata. Utilizzare list(, $caller) = debug_backtrace(false);per ottenere il chiamante, falseper le prestazioni ;-) (php5.3)
Znarkus,

Molte soluzioni viste sul Web ottengono il secondo elemento dell'array backtrace per ottenere il chiamante dell'istanza: possiamo esserne così sicuri? Il secondo elemento è sempre quello che stiamo cercando? Ho pensato che un __construct () che includesse all'interno di un'altra chiamata come parent :: __ construct () potesse spostare di un'altra posizione il vero chiamante (non ancora provato).
Emanuele Del Grande,

1
Ho provato a controllare l'ordine dei chiamanti restituiti durante l'utilizzo di una ReflectionClass e ovviamente cambia la posizione del metodo del chiamante "reale", che è visibile nell'interfaccia utente, quindi non è possibile ipotizzare la posizione di backtrace.
Emanuele Del Grande,

4
l'array shift rimuoverà il primo elemento e restituirà l'elemento rimosso. L'array originale verrà modificato e ciò dovrebbe fornire il risultato richiestoecho 'called by '.$trace[0]['function']
GoodSp33d

21
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];per ottenere il nome del chiamante con prestazioni migliori.
ahuigo,

17

Xdebug offre alcune funzioni interessanti.

<?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();
?>

restituirà traccia

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

Per installare Xdebug su Ubuntu il modo migliore è

sudo aptitude install php5-xdebug

Potrebbe essere necessario installare prima php5-dev

sudo aptitude install php5-dev

Ulteriori informazioni


15

Questo è molto tardi, ma vorrei condividere la funzione che darà il nome della funzione da cui viene chiamata la funzione corrente.

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;
    }

Spero sia utile.


1
Sei il benvenuto David !!! Sto anche usando questo per scopi di debug nel mio progetto :)
MANISH ZOPE

La modalità "traccia completa" è molto utile. Grazie per la condivisione.
Leopoldo Sanczyk,


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

Funziona da PHP 5.4 .

O ottimizzato (ad esempio per casi d'uso non di debug):

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

Il primo argomento impedisce di popolare argomenti di funzioni inutilizzate, il secondo limita la traccia a due livelli (è necessario il secondo).


7

Fatto questo e usando questo me stesso

/**
 * 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;
    }   
}

3

Volevo solo affermare che il modo di flori non funzionerà come una funzione perché restituirà sempre il nome della funzione chiamata invece del chiamante, ma non ho la reputazione di commentare. Ho fatto una funzione molto semplice basata sulla risposta di flori che funziona bene per il mio caso:

class basicFunctions{

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

}

ESEMPIO:

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..
}




1

Questo dovrebbe funzionare:

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

0

Questo lo farà bene:


// 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()
**/```
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.