PHPの呼び出し元関数の名前を取得しますか?


135

特定の関数の呼び出し元の関数の名前を見つけるPHP関数はありますか?


Xdebugを使用する必要があります。この記事では私の答えを参照してください: stackoverflow.com/questions/1513069/...
svassr

13
Xdebugは、元々のリクエストであるPHP関数ではありません。たとえば、後のPHPロジックで呼び出し元の関数名を使用し、本番サーバーにXDebugをインストールしない場合は、PHP関数が必要です。
JP

回答:


198

debug_backtraceを参照してください。これにより、呼び出しスタックを一番上まで追跡できます。

発信者を取得する方法は次のとおりです。

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

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

59
これは呼び出し先の関数名を出力しているようです。パフォーマンスのlist(, $caller) = debug_backtrace(false);ために、呼び出し元を取得するために使用しますfalse
;

Webで見られる多くのソリューションは、インスタンスの呼び出し元を取得するためにバックトレース配列の2番目の要素を取得します。2番目の要素は常に私たちが探しているものですか?parent :: __ construct()などの別の呼び出し内に含まれる__construct()は、実際の呼び出し元の別の位置にシフトする可能性があると考えました(まだ試していない)。
エマヌエーレデルグランデ

1
ReflectionClassを使用しているときに返された呼び出し元の順序を確認してみました。これにより、ユーザーインターフェイスに表示される「実際の」呼び出し元メソッドの位置が明らかに変化するため、バックトレースの位置を推測できません。
エマヌエーレデルグランデ

4
配列シフトは最初の要素を削除し、削除された要素を返します。元のアレイが変更され、必要な結果が得られるはずですecho 'called by '.$trace[0]['function']
GoodSp33d

21
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];より良いパフォーマンスで発信者名を取得します。
ahuigo 2015

17

Xdebugはいくつかの素晴らしい関数を提供します。

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

トレースを返します

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

Xdebugをubuntuにインストールするには、最善の方法は

sudo aptitude install php5-xdebug

最初にphp5-devをインストールする必要があるかもしれません

sudo aptitude install php5-dev

より詳しい情報


15

これは非常に遅いですが、現在の関数が呼び出される関数の名前を与える関数を共有したいと思います。

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

これがお役に立てば幸いです。


1
デビッド大歓迎です!!! 私のプロジェクトでもこれをデバッグの目的で使用しています:)
MANISH ZOPE

「完全トレース」モードは非常に便利です。共有いただきありがとうございます。
Leopoldo Sanczyk

15

debug_backtrace() パラメータの詳細、現在の呼び出しスタック内の関数/メソッド呼び出しを提供します。


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

PHP 5.4以降で動作します

または最適化(例:デバッグ以外のユースケース):

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

最初の引数は未使用の関数引数を設定することを防ぎ、2番目の引数はトレースを2つのレベルに制限します(2番目が必要です)。


7

これを作って自分で使った

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

floriの方法は常に呼び出し元ではなく呼び出された関数名を返すため、関数として機能しないことを述べたかったのですが、コメントについての評判はありません。私のケースではうまく機能する、フロリの答えに基づいて非常に単純な関数を作成しました。

class basicFunctions{

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

}

例:

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

これはうまくいくはずです:

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

0

これはうまくいきます:


// 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()
**/```
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.