Dapatkan nama fungsi pemanggil di PHP?

136

Apakah ada fungsi PHP untuk mengetahui nama fungsi pemanggil dalam fungsi tertentu?

miken32
sumber
Anda harus menggunakan Xdebug. Lihat jawaban saya di posting ini: stackoverflow.com/questions/1513069/…
svassr
13
Xdebug secara kategoris bukan hanya fungsi PHP, yang merupakan permintaan asli. Jika Anda ingin misalnya menggunakan nama fungsi pemanggil di logika PHP nanti dan tidak menginstal XDebug di server produksi, Anda memerlukan fungsi PHP.
JP

Jawaban:

201

Lihat debug_backtrace - ini bisa melacak tumpukan panggilan Anda sampai ke atas.

Inilah cara Anda mendapatkan penelepon:

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

echo "Called by {$caller['function']}";
if (isset($caller['class']))
    echo " in {$caller['class']}";
Paul Dixon
sumber
59
Tampaknya bagi saya ini mencetak nama fungsi callee. Gunakan list(, $caller) = debug_backtrace(false);untuk mendapatkan penelepon, falseuntuk kinerja ;-) (php5.3)
Znarkus
Banyak solusi yang terlihat di web mendapatkan elemen kedua dari larik backtrace untuk mendapatkan pemanggil instance: dapatkah kita begitu yakin? Apakah elemen kedua selalu yang kita cari? Saya pikir __construct () yang termasuk di dalam panggilan lain seperti parent :: __ construct () bisa menggeser posisi lain pemanggil sebenarnya (belum mencoba).
yodabar
1
Saya mencoba memeriksa urutan penelepon yang dikembalikan saat menggunakan ReflectionClass, dan ini jelas mengubah posisi metode pemanggil "sebenarnya", yang terlihat di antarmuka pengguna, jadi tidak ada asumsi tentang posisi lacak balik yang dapat dibuat.
yodabar
4
Pergeseran array akan menghapus elemen pertama dan mengembalikan elemen yang dihapus. Array asli akan dimodifikasi dan ini akan memberikan hasil yang diperlukanecho 'called by '.$trace[0]['function']
GoodSp33d
22
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];untuk mendapatkan nama pemanggil dengan kinerja yang lebih baik.
ahuigo
17

Xdebug menyediakan beberapa fungsi yang bagus.

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

akan mengembalikan jejak

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

Untuk menginstal Xdebug di ubuntu cara terbaik adalah

sudo aptitude install php5-xdebug

Anda mungkin perlu menginstal php5-dev terlebih dahulu

sudo aptitude install php5-dev

Info lebih lanjut

svassr
sumber
16

Ini sangat terlambat tetapi saya ingin membagikan fungsi yang akan memberi nama fungsi dari mana fungsi saat ini dipanggil.

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

Semoga bermanfaat.

MANISH ZOPE
sumber
Mode "jejak lengkap" sangat berguna. Terima kasih telah berbagi.
Leopoldo Sanczyk
15

debug_backtrace() menyediakan detail parameter, panggilan fungsi / metode dalam stack panggilan saat ini.

Christian C. Salvadó
sumber
10
echo debug_backtrace()[1]['function'];

Bekerja sejak PHP 5.4 .

Atau dioptimalkan (misalnya untuk kasus penggunaan non-debug):

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

Argumen pertama mencegah untuk mengisi argumen fungsi yang tidak digunakan, yang kedua membatasi jejak ke dua tingkat (kita memerlukan yang kedua).

flori
sumber
7

Membuat ini dan menggunakan ini sendiri

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

Saya hanya ingin menyatakan bahwa cara flori tidak akan berfungsi sebagai fungsi karena akan selalu mengembalikan nama fungsi yang dipanggil alih-alih pemanggil, tetapi saya tidak memiliki reputasi untuk berkomentar. Saya membuat fungsi yang sangat sederhana berdasarkan jawaban flori yang berfungsi dengan baik untuk kasus saya:

class basicFunctions{

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

}

CONTOH:

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
sumber
2

Anda dapat mengekstrak informasi ini dari larik yang dikembalikan oleh debug_backtrace

Richard Turner
sumber
2

Yang ini paling berhasil untuk saya: var_dump(debug_backtrace());

Gershon Herczeg
sumber
1

Ini harus bekerja:

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

Ini akan melakukannya dengan baik:


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