apakah ada cara untuk mengetahui, dari mana fungsi dalam PHP dipanggil? contoh:
function epic()
{
fail();
}
function fail()
{
//at this point, how do i know, that epic() has called this function?
}
Jawaban:
Anda bisa menggunakan debug_backtrace()
.
Contoh:
<?php
function epic( $a, $b )
{
fail( $a . ' ' . $b );
}
function fail( $string )
{
$backtrace = debug_backtrace();
print_r( $backtrace );
}
epic( 'Hello', 'World' );
Keluaran:
Array
(
[0] => Array
(
[file] => /Users/romac/Desktop/test.php
[line] => 5
[function] => fail
[args] => Array
(
[0] => Hello World
)
)
[1] => Array
(
[file] => /Users/romac/Desktop/test.php
[line] => 15
[function] => epic
[args] => Array
(
[0] => Hello
[1] => World
)
)
)
Penggunaan debug_backtrace()
:
function fail()
{
$backtrace = debug_backtrace();
// Here, $backtrace[0] points to fail(), so we'll look in $backtrace[1] instead
if (isset($backtrace[1]['function']) && $backtrace[1]['function'] == 'epic')
{
// Called by epic()...
}
}
debug_backtrace()
adalah panggilan yang mahal. Jangan biasakan menggunakannya untuk menentukan rantai panggilan. Jika Anda ingin "melindungi" fungsi tersebut, lihat OOP dan metode yang dilindungi.
Solusi tercepat dan termudah yang saya temukan
public function func() { //function whose call file you want to find
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
}
$trace: Array
(
[0] => Array
(
[file] => C:\wamp\www\index.php
[line] => 56
[function] => func
[class] => (func Class namespace)
[type] => ->
)
)
Saya menguji kecepatan pada laptop Lenovo: Intel Pentiom CPU N3530 2.16GHz, RAM 8GB
global $times;
$start = microtime(true);
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
$times[] = microtime(true) - $start;
Hasil:
count($times): 97
min: 2.6941299438477E-5
max: 10.68115234375E-5
avg: 3.3095939872191E-5
median: 3.0517578125E-5
sum: 321.03061676025E-5
the same results with notation without E-5
count($times): 97
min: 0.000026941299438477
max: 0.0001068115234375
avg: 0.000033095939872191
median: 0.000030517578125
sum: 0.0032103061676025
Jadi jika Anda masih BENAR-BENAR tidak tahu caranya, berikut solusinya:
$backtrace = debug_backtrace();
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!';
Gunakan fungsi debug_backtrace: http://php.net/manual/en/function.debug-backtrace.php
Coba kode di bawah ini.
foreach(debug_backtrace() as $t) {
echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>";
}
Jika Anda ingin melacak asal panggilan yang tepat di bagian atas tumpukan, Anda dapat menggunakan kode berikut:
$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
Ini akan mengabaikan fungsi yang dirantai dan hanya mendapatkan info panggilan yang paling relevan (relevan digunakan secara longgar karena bergantung pada apa yang ingin Anda capai).
function findFunction($function, $inputDirectory=""){
//version 0.1
$docRoot = getenv("DOCUMENT_ROOT");
$folderArray = null;
$dirArray = null;
// open directory
$directory = opendir($docRoot.$inputDirectory);
// get each entry
while($entryName = readdir($directory)) {
if(is_dir($entryName) && $entryName != "." && $entryName != ".."){
$folderArray[] = str_replace($inputDirectory, "", $entryName);
}
$ext = explode(".", $entryName);
if(!empty($ext[1])){
$dirArray[] = $docRoot.$inputDirectory."/".$entryName;
}
}
// close directory
closedir($directory);
$found = false;
if(is_array($dirArray)){
foreach($dirArray as $current){
$myFile = file_get_contents($current);
$myFile = str_replace("<?php", "", $myFile);
$myFile = str_replace("?>", "", $myFile);
if(preg_match("/function ".$function."/", $myFile)){
$found = true;
$foundLocation = $current;
break;
}
}
}
if($found){
echo $foundLocation;
exit;
} else if(is_array($folderArray)){
foreach($folderArray as $folder){
if(!isset($return)){
$return = findFunction($function, $inputDirectory."/".$folder);
} else if($return == false){
$return = findFunction($function, $inputDirectory."/".$folder);
}
}
} else {
return false;
}
}
findFunction("testFunction", "rootDirectory");
Semoga bisa membantu seseorang. Jika fungsi sebenarnya berada di luar httpdocs maka itu tidak dapat ditemukan karena server akan diatur untuk tidak mengizinkannya. Hanya mengujinya dalam satu folder juga tetapi metodologi rekursif harus bekerja dalam teori.
Ini seperti versi 0.1 tetapi saya tidak bermaksud melanjutkan pengembangan di atasnya jadi jika seseorang memperbaruinya, silakan memposting ulang.
function ff() { grep "function $1" $(find ./ -name "*.php") }
lalu panggil ff fail
atau ff epic
. lihat: github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122
debug_backtrace()
fungsi yang luar biasa. Saya akan menggunakan yang ini!