পিএইচপি: ফাংশনটি কোথা থেকে ডাকা হয়েছিল তা নির্ধারণ করুন


94

পিএইচপি-তে কোনও ফাংশন কোথা থেকে ডেকে আনা হয়েছিল, তা খুঁজে বের করার কোনও উপায় আছে? উদাহরণ:

function epic()
{
  fail();
}

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

উত্তর:


130

আপনি ব্যবহার করতে পারেন 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
                )

        )

)

4
প্রথমবার আমি খুঁজে পেলাম 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()একটি ব্যয়বহুল ডাক। কল-চেইন নির্ধারণের জন্য এটি ব্যবহার করার অভ্যাসে যাবেন না। আপনি যদি এই ফাংশনগুলিকে "সুরক্ষা" দিতে চান তবে ওওপি এবং সুরক্ষিত পদ্ধতিগুলি দেখুন।
একারম্যাক্সেল

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

)

আমি লেনোভো ল্যাপটপে গতি পরীক্ষা করি: ইন্টেল পেন্টিয়াম সিপিইউ N3530 2.16GHz, র‌্যাম 8 জিবি

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!';

4
সুতরাং আপনি যদি ব্যবহার করতে পারেন ($ backtrace [1] ['ফাংশন'] == 'মহাকাব্য') {// কিছু স্টাফ করেন; অন্য কিছু জিনিস করা; } ?? বাহ
বাটল বাটকাস

4
হ্যাঁ, কিন্তু না! যাইহোক, স্থায়ী অ্যাপ্লিকেশন কোডে নেই। পরামিতি ব্যবহার করুন। ডিবাগ_ব্যাকট্রেস () দেখতে বেশ ভারী অপারেশন বলে মনে হচ্ছে।
ক্লুনি


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") } তারপর কল ff failবা ff epic। দেখুন: github.com/MaerF0x0/VimSetup/blob/master/bashrc#L122
মাইক গ্রাফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.