Uzyskaj nazwę funkcji dzwoniącego w PHP?

135

Czy istnieje funkcja PHP, aby znaleźć nazwę funkcji wywołującej w danej funkcji?

miken32
źródło
Powinieneś użyć Xdebug. Zobacz moją odpowiedź w tym poście: stackoverflow.com/questions/1513069/…
svassr
13
Xdebug to kategorycznie nie tylko funkcja PHP, która była pierwotnym żądaniem. Jeśli chcesz np. Użyć nazwy funkcji wywołującej w późniejszej logice PHP i nie instalować XDebug na serwerach produkcyjnych, potrzebujesz funkcji PHP.
JP,

Odpowiedzi:

198

Zobacz debug_backtrace - to może prześledzić twój stos wywołań aż do samego początku.

Oto, jak możesz zdobyć dzwoniącego:

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

echo "Called by {$caller['function']}";
if (isset($caller['class']))
    echo " in {$caller['class']}";
Paul Dixon
źródło
59
Wydaje mi się, że wypisuje to nazwę funkcji wywoływanej. Użyj, list(, $caller) = debug_backtrace(false);aby uzyskać dzwoniącego, falsedo wykonania ;-) (php5.3)
Znarkus
Wiele rozwiązań dostępnych w sieci pobiera drugi element tablicy śledzenia wstecznego, aby uzyskać wywołujący instancję: czy możemy być tego tak pewni? Czy zawsze szukamy drugiego elementu? Pomyślałem, że __construct (), który zawiera wewnątrz innego wywołania, takiego jak parent :: __ construct (), może przesunąć o inną pozycję prawdziwego wywołującego (jeszcze nie próbowałem).
Emanuele Del Grande,
1
Próbowałem sprawdzić kolejność wywołań zwracanych podczas korzystania z ReflectionClass i oczywiście zmienia to pozycję „prawdziwej” metody wywołującej, która jest widoczna w interfejsie użytkownika, więc nie można poczynić żadnych założeń dotyczących pozycji śledzenia wstecznego.
Emanuele Del Grande,
4
array shift usunie pierwszy element i zwróci usunięty element. Oryginalna tablica zostanie zmodyfikowana, co powinno dać wymagany wynikecho 'called by '.$trace[0]['function']
GoodSp33d
21
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];aby uzyskać nazwę dzwoniącego z lepszą wydajnością.
ahuigo
17

Xdebug zapewnia kilka fajnych funkcji.

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

zwróci ślad

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

Aby zainstalować Xdebug na Ubuntu, najlepszym sposobem jest

sudo aptitude install php5-xdebug

Być może będziesz musiał najpierw zainstalować php5-dev

sudo aptitude install php5-dev

więcej informacji

svassr
źródło
15

To bardzo późno, ale chciałbym udostępnić funkcję, która poda nazwę funkcji, z której jest wywoływana bieżąca funkcja.

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

Mam nadzieję, że to się przyda.

MANISH ZOPE
źródło
1
Nie ma za co, David !!! Używam tego również do debugowania w moim projekcie :)
MANISH ZOPE
Tryb „pełnego śledzenia” jest bardzo przydatny. Dzięki za udostępnienie.
Leopoldo Sanczyk
15

debug_backtrace() dostarcza szczegóły parametrów, wywołań funkcji / metod w bieżącym stosie wywołań.

CMS
źródło
9
echo debug_backtrace()[1]['function'];

Działa od PHP 5.4 .

Lub zoptymalizowany (np. Dla przypadków użycia innych niż debugowanie):

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

Pierwszy argument zapobiega wypełnianiu nieużywanych argumentów funkcji, drugi ogranicza śledzenie do dwóch poziomów (potrzebujemy drugiego).

flori
źródło
7

Zrobiłem to i używając tego sam

/**
 * 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
źródło
3

Chciałem tylko powiedzieć, że sposób flori nie będzie działał jako funkcja, ponieważ zawsze zwróci nazwę wywoływanej funkcji zamiast wywołującego, ale nie mam reputacji komentowania. Stworzyłem bardzo prostą funkcję opartą na odpowiedzi flori, która działa dobrze w moim przypadku:

class basicFunctions{

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

}

PRZYKŁAD:

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
źródło
2

Możesz wyodrębnić te informacje z tablicy zwróconej przez debug_backtrace

Richard Turner
źródło
2

Ten działał najlepiej dla mnie: var_dump(debug_backtrace());

Gershon Herczeg
źródło
1

To powinno działać:

$caller = next(debug_backtrace())['function'];
kenorb
źródło
0

To ładnie to zrobi:


// 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
źródło