2010-06-02 13 views

Odpowiedz

21

Zastosowanie 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()... 
    } 
} 
+7

To zdecydowanie robi to, co chcesz. Ale uważaj, 'debug_backtrace()' jest kosztownym połączeniem. Nie miej zwyczaju używać go do określania łańcuchów wywołań. Jeśli chcesz "chronić" te funkcje, sprawdź OOP i metody chronione. – ircmaxell

+0

bardzo dziękuję wszystkim! –

107

Można użyć debug_backtrace().

Przykład:

<?php 

function epic($a, $b) 
{ 
    fail($a . ' ' . $b); 
} 

function fail($string) 
{ 
    $backtrace = debug_backtrace(); 

    print_r($backtrace); 
} 

epic('Hello', 'World'); 

wyjściowa:

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 
       ) 

     ) 

) 
+2

Po raz pierwszy znalazłem 'debug_backtrace()' co za znakomita funkcja. Będę używał tego! –

-1
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"); 

Nadzieja pomaga kogoś. Jeśli rzeczywista funkcja jest poza skryptami httpdocs, nie można jej znaleźć, ponieważ serwer zostanie skonfigurowany, aby nie zezwalać na to. Przetestowałem go tylko w jednym folderze, ale metodologia rekurencyjna powinna działać w teorii.

To jest jak wersja 0.1, ale nie zamierzam kontynuować jej rozwoju, więc jeśli ktoś ją zaktualizuje, możesz ją ponownie opublikować.

+0

Za dużo pracy: dodaj to do .bashrc 'function ff() { grep" funkcja $ 1 "$ (znajdź ./ -name" * .php ") }' następnie wywołaj 'ff fail' lub' ff epic '. zobacz: https: // github.com/MaerF0x0/VimSetup/blob/master/bashrC# L122 –

12

Więc jeśli jeszcze naprawdę nie wiem, w jaki sposób, niż tu jest rozwiązanie:

$backtrace = debug_backtrace(); 
echo 'Mu name is '.$backtrace[1]['function'].', and I have called him! Muahahah!'; 
+1

Możesz użyć, jeśli ($ backtrace [1] ['function'] == 'epic') {// wykonaj kilka czynności; w innym razie rób inne rzeczy; } ?? wow. –

+1

Tak, ale nie rób tego! W każdym razie nie w stałym kodzie aplikacji. Użyj parametrów. debug_backtrace() wygląda na dość ciężką operację. – Kluny

2

Spróbuj poniżej kodu.

foreach(debug_backtrace() as $t) {    
    echo $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()<br/>"; 
} 
9

Najszybsze i najprostsze rozwiązanie jak znalazłem

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] => -> 
     ) 

) 

przetestować prędkość na laptopie Lenovo: Intel Pentiom CPU N3530 2,16 GHz, RAM 8GB

global $times; 
$start = microtime(true); 
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); 
$times[] = microtime(true) - $start; 

wyniki:

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.3061676025 
+0

Dla mnie DEBUG_BACKTRACE_IGNORE_ARGS był bardzo przydatny, bez niego było o wiele za dużo informacji. – Arie

0

Jeśli chcesz prześledzić e dokładne pochodzenie rozmowy na szczycie stosu można użyć następującego kodu:

$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); 

To będzie ignorować łańcuchu funkcje i dostać tylko najbardziej istotnych informacji o połączeniu (istotne jest stosowany luźno jak to zależy, co się próbujemy osiągnąć).

Powiązane problemy