รับชื่อฟังก์ชันผู้โทรใน PHP หรือไม่


136

มีฟังก์ชัน PHP เพื่อค้นหาชื่อของฟังก์ชันผู้โทรในฟังก์ชันที่กำหนดหรือไม่?


คุณควรใช้ Xdebug ดูคำตอบของฉันในโพสต์นี้: stackoverflow.com/questions/1513069/…
svassr

13
Xdebug ไม่ได้เป็นเพียงฟังก์ชัน PHP ซึ่งเป็นคำขอดั้งเดิม หากคุณต้องการใช้ชื่อฟังก์ชันผู้โทรในลอจิก PHP ในภายหลังและไม่ติดตั้ง XDebug บนเซิร์ฟเวอร์ที่ใช้งานจริงคุณต้องมีฟังก์ชัน PHP
JP

คำตอบ:


201

ดูdebug_backtraceซึ่งสามารถติดตาม call stack ของคุณไปจนถึงด้านบนสุด

วิธีรับผู้โทร:

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

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

59
สำหรับฉันแล้วสิ่งนี้จะพิมพ์ชื่อฟังก์ชัน callee ใช้list(, $caller) = debug_backtrace(false);รับผู้โทรfalseเพื่อประสิทธิภาพ ;-) (php5.3)
Znarkus

โซลูชันจำนวนมากที่เห็นบนเว็บรับองค์ประกอบที่สองของอาร์เรย์ backtrace เพื่อรับอินสแตนซ์ผู้เรียก: เราแน่ใจได้ไหม องค์ประกอบที่สองเป็นสิ่งที่เรากำลังค้นหาอยู่เสมอหรือไม่? ฉันคิดว่า __construct () ซึ่งรวมถึงการเรียกอื่นเช่น parent :: __ build () สามารถเปลี่ยนตำแหน่งอื่นที่ผู้โทรจริง (ยังไม่ได้ลอง)
yodabar

1
ฉันลองตรวจสอบลำดับของผู้โทรที่ส่งกลับในขณะที่ใช้ ReflectionClass และเห็นได้ชัดว่ามันเปลี่ยนตำแหน่งของวิธีการโทร "จริง" ซึ่งมองเห็นได้ในอินเทอร์เฟซผู้ใช้ดังนั้นจึงไม่สามารถตั้งสมมติฐานเกี่ยวกับตำแหน่ง backtrace ได้
yodabar

4
อาร์เรย์กะจะลบองค์ประกอบแรกและส่งคืนองค์ประกอบที่ถูกลบ อาร์เรย์เดิมจะได้รับการแก้ไขและสิ่งนี้ควรให้ผลลัพธ์ที่ต้องการecho 'called by '.$trace[0]['function']
GoodSp33d

22
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];เพื่อให้ได้ชื่อผู้โทรที่มีประสิทธิภาพที่ดีขึ้น
ahuigo

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

ข้อมูลเพิ่มเติม


16

นี่มันสายไปแล้ว แต่ฉันอยากจะแชร์ฟังก์ชั่นที่จะให้ชื่อของฟังก์ชันที่เรียกใช้ฟังก์ชันปัจจุบัน

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

ฉันหวังว่านี่จะเป็นประโยชน์


โหมด "การติดตามที่สมบูรณ์" มีประโยชน์มาก ขอบคุณสำหรับการแบ่งปัน.
Leopoldo Sanczyk


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

การทำงานตั้งแต่PHP 5.4

หรือปรับให้เหมาะสม (เช่นสำหรับกรณีการใช้งานที่ไม่แก้ไขจุดบกพร่อง):

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

อาร์กิวเมนต์แรกป้องกันไม่ให้เติมอาร์กิวเมนต์ของฟังก์ชันที่ไม่ได้ใช้ส่วนที่สอง จำกัด การติดตามเป็นสองระดับ (เราต้องการที่สอง)


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 จะไม่ทำงานเป็นฟังก์ชันเพราะมันจะส่งคืนชื่อฟังก์ชันที่เรียกแทนตัวเรียกเสมอ แต่ฉันไม่มีชื่อเสียงในการแสดงความคิดเห็น ฉันสร้างฟังก์ชั่นที่เรียบง่ายตามคำตอบของ 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..
}





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.