Comment obtenir le nom de la fonction/méthode d'appel en PHP? [dupliquer]

Cette question a déjà une réponse ici:

Je suis au courant de function debug_backtrace, mais je cherche une implémentation prête à l'emploi de function comme GetCallingMethodName()? Ce serait parfait si cela donnait aussi la classe de method (si c'est bien une méthode).

168
php
demandé sur meagar 2010-01-21 19:10:17

10 réponses

La fonction debug_backtrace() est la seule façon de le savoir, si vous êtes paresseux, c'est une raison de plus que vous devriez coder le GetCallingMethodName() vous-même. Combattez la paresse! :D

117
répondu Alix Axel 2010-01-21 16:13:12

Le moyen le plus simple est:

echo debug_backtrace()[1]['function'];
401
répondu diyism 2018-02-28 04:56:58

Depuis php 5.4 vous pouvez utiliser

        $dbt=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2);
        $caller = isset($dbt[1]['function']) ? $dbt[1]['function'] : null;

Cela ne gaspillera pas de mémoire car il ignore les arguments et ne renvoie que les 2 dernières entrées de la pile backtrace, et ne générera pas de notices comme d'autres réponses ici.

28
répondu idragosalex 2015-02-19 09:02:20

Vous pouvez également utiliser les informations fournies par une exception php, c'est une solution élégante:


function GetCallingMethodName(){
    $e = new Exception();
    $trace = $e->getTrace();
    //position 0 would be the line that called this function so we ignore it
    $last_call = $trace[1];
    print_r($last_call);
}

function firstCall($a, $b){
    theCall($a, $b);
}

function theCall($a, $b){
    GetCallingMethodName();
}

firstCall('lucia', 'php');

Et vous obtenez ceci... (voilà!)

Array
(
    [file] => /home/lufigueroa/Desktop/test.php
    [line] => 12
    [function] => theCall
    [args] => Array
        (
            [0] => lucia
            [1] => php
        )

)
22
répondu Lucia 2012-02-03 18:50:42

Ma façon préférée, en une seule ligne!

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

, Vous pouvez l'utiliser comme ceci:

echo 'The calling function: ' . debug_backtrace()[1]['function'];

Notez que ceci n'est compatible qu'avec les versions de PHP publiées au cours de la dernière année. Mais c'est une bonne idée de garder votre PHP à jour de toute façon pour des raisons de sécurité.

16
répondu gavanon 2014-11-05 18:12:19

Pour moi, debug_backtrace atteignait ma limite de mémoire, et je voulais l'utiliser en production pour enregistrer et envoyer des erreurs au fur et à mesure.

Au lieu de cela, j'ai trouvé cette solution qui fonctionne avec brio!

// Make a new exception at the point you want to trace, and trace it!
$e = new Exception;
var_dump($e->getTraceAsString());

// Outputs the following 
#2 /usr/share/php/PHPUnit/Framework/TestCase.php(626): SeriesHelperTest->setUp()
#3 /usr/share/php/PHPUnit/Framework/TestResult.php(666): PHPUnit_Framework_TestCase->runBare()
#4 /usr/share/php/PHPUnit/Framework/TestCase.php(576): PHPUnit_Framework_TestResult->run(Object(SeriesHelperTest))
#5 /usr/share/php/PHPUnit/Framework/TestSuite.php(757): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
#6 /usr/share/php/PHPUnit/Framework/TestSuite.php(733): PHPUnit_Framework_TestSuite->runTest(Object(SeriesHelperTest), Object(PHPUnit_Framework_TestResult))
#7 /usr/share/php/PHPUnit/TextUI/TestRunner.php(305): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false)
#8 /usr/share/php/PHPUnit/TextUI/Command.php(188): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array)
#9 /usr/share/php/PHPUnit/TextUI/Command.php(129): PHPUnit_TextUI_Command->run(Array, true)
#10 /usr/bin/phpunit(53): PHPUnit_TextUI_Command::main()
#11 {main}"
12
répondu Anil 2014-02-27 10:53:15

Je viens d'écrire une version de ceci appelée "get_caller", j'espère que cela aide. Le mien est plutôt paresseux. Vous pouvez simplement exécuter get_caller() à partir d'une fonction, vous n'avez pas à la spécifier comme ceci:

get_caller(__FUNCTION__);

Voici le script dans son intégralité avec un cas de test original:

<?php

/* This function will return the name string of the function that called $function. To return the
    caller of your function, either call get_caller(), or get_caller(__FUNCTION__).
*/
function get_caller($function = NULL, $use_stack = NULL) {
    if ( is_array($use_stack) ) {
        // If a function stack has been provided, used that.
        $stack = $use_stack;
    } else {
        // Otherwise create a fresh one.
        $stack = debug_backtrace();
        echo "\nPrintout of Function Stack: \n\n";
        print_r($stack);
        echo "\n";
    }

    if ($function == NULL) {
        // We need $function to be a function name to retrieve its caller. If it is omitted, then
        // we need to first find what function called get_caller(), and substitute that as the
        // default $function. Remember that invoking get_caller() recursively will add another
        // instance of it to the function stack, so tell get_caller() to use the current stack.
        $function = get_caller(__FUNCTION__, $stack);
    }

    if ( is_string($function) && $function != "" ) {
        // If we are given a function name as a string, go through the function stack and find
        // it's caller.
        for ($i = 0; $i < count($stack); $i++) {
            $curr_function = $stack[$i];
            // Make sure that a caller exists, a function being called within the main script
            // won't have a caller.
            if ( $curr_function["function"] == $function && ($i + 1) < count($stack) ) {
                return $stack[$i + 1]["function"];
            }
        }
    }

    // At this stage, no caller has been found, bummer.
    return "";
}

// TEST CASE

function woman() {
    $caller = get_caller(); // No need for get_caller(__FUNCTION__) here
    if ($caller != "") {
        echo $caller , "() called " , __FUNCTION__ , "(). No surprises there.\n";
    } else {
        echo "no-one called ", __FUNCTION__, "()\n";
    }
}

function man() {
    // Call the woman.
    woman();
}

// Don't keep him waiting
man();

// Try this to see what happens when there is no caller (function called from main script)
//woman();

?>

L'Homme() appelle la femme(), qui appelle get_caller(). get_caller () ne sait pas encore qui l'a appelé, parce que la femme() était prudente et ne l'a pas dit, donc elle se répète pour le savoir. Ensuite, il revient qui a appelé femme (). Et l'impression dans le mode code source dans un navigateur affiche la pile de fonctions:

Printout of Function Stack: 

Array
(
    [0] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 46
            [function] => get_caller
            [args] => Array
                (
                )

        )

    [1] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 56
            [function] => woman
            [args] => Array
                (
                )

        )

    [2] => Array
        (
            [file] => /Users/Aram/Development/Web/php/examples/get_caller.php
            [line] => 60
            [function] => man
            [args] => Array
                (
                )

        )

)

man() called woman(). No surprises there.
8
répondu Aram Kocharyan 2011-01-22 13:28:29

J'avais besoin de quelque chose pour lister simplement les classes/méthodes d'appel (travaillant sur un projet Magento).

Alors que debug_backtrace fournit des tonnes d'informations utiles, la quantité d'informations qu'il a vomi pour L'installation de Magento était écrasante (plus de 82 000 lignes!) Comme je ne m'intéressais qu'à la fonction d'appel et à la classe, j'ai travaillé cette petite solution:

$callers=debug_backtrace();
foreach($callers as $call) {
    echo "<br>" . $call['class'] . '->' . $call['function'];
}
3
répondu cale_b 2013-06-20 18:07:59

Le moyen le plus simple d'obtenir le nom de la fonction parent est:

$caller = next(debug_backtrace())['function'];
3
répondu kenorb 2014-05-23 11:15:54

La meilleure réponse à cette question que j'ai vue est:

list(, $caller) = debug_backtrace(false);

Court et propre

0
répondu infinity 2012-12-11 10:15:43