2010-06-02 27 views
78

से कहां से फ़ंक्शन कहा गया था, क्या यह पता लगाने का कोई तरीका है कि PHP में कोई फ़ंक्शन कहलाता था? उदाहरण:php: निर्धारित करें कि

function epic() 
{ 
    fail(); 
} 

function fail() 
{ 
    //at this point, how do i know, that epic() has called this function? 
} 

उत्तर

21

उपयोग 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

यह निश्चित रूप से आप जो चाहते हैं वह करता है। लेकिन सावधान रहें 'debug_backtrace() 'एक महंगी कॉल है। कॉल-चेन निर्धारित करने के लिए इसका उपयोग करने की आदत में न आएं। यदि आप उन कार्यों को "सुरक्षित" करना चाहते हैं, तो ओओपी और संरक्षित विधियों की जांच करें। – ircmaxell

+0

आप सभी को बहुत बहुत धन्यवाद! –

107

आप debug_backtrace() उपयोग कर सकते हैं।

उदाहरण:

<?php 

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

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

    print_r($backtrace); 
} 

epic('Hello', 'World'); 

आउटपुट:

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

पहली बार मुझे 'debug_backtrace() 'एक शानदार कार्य मिला। मैं इसका इस्तेमाल करूँगा! –

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

आशा है कि यह किसी को मदद मिलती है। यदि वास्तविक फ़ंक्शन httpdocs के बाहर है तो यह नहीं पाया जा सकता है क्योंकि सर्वर इसे अनुमति देने के लिए सेटअप नहीं होगा। केवल एक गहराई से एक फ़ोल्डर का परीक्षण किया लेकिन पुनरावर्ती पद्धति सिद्धांत में काम करना चाहिए।

यह संस्करण 0.1 की तरह है, लेकिन मुझे इस पर निरंतर विकास का इरादा नहीं है, इसलिए अगर कोई अपडेट करता है तो इसे दोबारा मुक्त करने में संकोच न करें।

+0

बहुत ज्यादा काम: इस ऐड '.bashrc के लिए समारोह एफएफ() { grep" समारोह $ 1 "$ (./ -name" * .php "लगता है) }' तो फोन 'एफएफ fail' या' एफएफ महाकाव्य '। देखें: https: // github।com/MaerF0x0/VimSetup/blob/master/bashrC# L122 –

12

तो अगर आप अभी भी वास्तव में पता नहीं कैसे, समाधान है यहाँ से:

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

तो यदि आप ($ backtrace [1] ['function'] == 'epic') {// कुछ सामान करते हैं तो आप इसका उपयोग कर सकते हैं; और कुछ और सामान करो; } ?? वाह –

+1

हाँ, लेकिन नहीं! वैसे भी स्थायी आवेदन कोड में नहीं। पैरामीटर का प्रयोग करें। debug_backtrace() एक बहुत भारी ऑपरेशन की तरह दिखता है। – Kluny

2

कोड के नीचे की कोशिश करो।

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

सबसे तेज और आसान समाधान मैंने पाया के रूप में

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

) 

मैं लेनोवो लैपटॉप पर गति का परीक्षण: इंटेल Pentiom सीपीयू N3530 2.16GHz, रैम 8GB

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

परिणाम:

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

मेरे लिए DEBUG_BACKTRACE_IGNORE_ARGS बहुत उपयोगी था, इसके बिना बहुत अधिक जानकारी थी। – Arie

0

यदि आप ट्रैक करना चाहते हैं ई ढेर आप निम्नलिखित कोड का उपयोग कर सकते के शीर्ष पर कॉल की सटीक मूल:

$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); 

इस श्रृंखलित कार्यों पर ध्यान न दें और केवल सबसे प्रासंगिक कॉल की जानकारी (प्राप्त प्रासंगिक होगा शिथिल प्रयोग किया जाता है के रूप में यह निर्भर करता है कि आपके पूरा करने की कोशिश कर रहे हैं)।

संबंधित मुद्दे