php: निर्धारित करें कि फ़ंक्शन कहाँ से बुलाया गया था


93

क्या पता लगाने का एक तरीका है, जहां PHP में एक फ़ंक्शन कहा जाता है? उदाहरण:

function epic()
{
  fail();
}

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

जवाबों:


129

आप उपयोग कर सकते हैं 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
                )

        )

)

5
पहली बार मैंने पाया debug_backtrace()कि क्या शानदार फंक्शन है। मैं इस एक का उपयोग कर रहा हूँ!
डेविड येल

26

उपयोग करें 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()...
    }
}

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

18

सबसे तेज और सरल उपाय जैसा कि मैंने पाया

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

)

मैं लेनोवो लैपटॉप पर गति का परीक्षण करता हूं: 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;

परिणाम:

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

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

15

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

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

1
तो आप उपयोग कर सकते हैं अगर ($ backtrace [1] ['फ़ंक्शन'] == 'महाकाव्य') {// कुछ सामान करते हैं; कुछ और सामान करो; } ?? वाह
ब्यूटेल बटुक 4

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


3

कोड के नीचे प्रयास करें।

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

सभी फ़ाइलों का पता लगाने के लिए अच्छा और सीधा समाधान जिसमें से किसी विशेष फ़ंक्शन को कहा जाता है।
अपवाद

3

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

$call_origin = end(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));

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


धन्यवाद।
मोहम्मद संकोच

-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 की तरह है, लेकिन मैं इस पर निरंतर विकास का इरादा नहीं रखता हूं, अगर कोई इसे अपडेट करता है तो इसे फिर से शुरू करने के लिए स्वतंत्र महसूस करता है।


बहुत अधिक काम: इसे .bashrc में जोड़ें या function ff() { grep "function $1" $(find ./ -name "*.php") } फिर कॉल करें । देखें: github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122ff failff epic
माइक ग्राफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.