#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2016
    Location
    Lakewood, WA
    Posts
    76
    Rep Power
    17

    Using debug_backtrace() to determine calling function...


    I have a library of related functions wrapped up in a class (many of the functions use other functions in the same class). With several, I'd like to know which function called them so as to tailor the output.

    I've experimented with debug_backtrace(), and it seems to do what I want.

    For example:
    PHP Code:
    if ((debug_backtrace()[1]['function']) == "some_function_name") {
        
    // Do something...
    } else {
        
    // Do something else...

    Is there a reason why I shouldn't do it this way?

    Is debug_backtrace() a resource hog, for example?
  2. #2
  3. Confusing Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    15,932
    Rep Power
    9570
    Yes, it's expensive as it requires going through the whole call stack and pulling information from the PHP internals.

    And yes, you shouldn't do it that way for a simple reason: unpredictability. If I'm writing code that calls this function, how do I know what it will output if it decides on its own what to do? What if I need specific output and the function decides to do something else instead?

    And another reason: separation of concerns. The function should only have to care about what it does. It shouldn't have to know about code all over the rest of the codebase because that's a maintenance nightmare and it would be so easy to add a function somewhere that needs a form of output already supported without remembering that this function needs to be edited as well to support it.

    A third: backtraces aren't simple like that. You may think [1] is the previous function but that's not always the case. The call may have gone through an internal function first, and those don't always (last I knew) produce complete stack frames - best case you get the internal function name, which isn't helpful. If the code goes through an assertion then that screws things up too.

    And one more: feasibility. What if the call have happened through another userland function first, and the output should actually vary based on [2] or [3] or further? Do you have to go through the stack finding the first applicable function call? What if the function is called from a file scope and not a function? Your backtrace would identify include/require/_once when the file was included, and incorporating a check for the calling file would be crazy because then you'd have to calculate relative paths.

    The decision should always be up to the calling function because it's the place that knows what it needs. The called function should not have to guess and the caller should not have to hope it guesses correctly.

    If you want to vary output, add an argument for it. Also consider whether you should split the function into more: one to do whatever work is needed prior to the output and return the result, the other functions for the different ways to output it.

    Comments on this post

    • oakleaf agrees
    Last edited by requinix; February 3rd, 2017 at 02:09 AM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2015
    Posts
    50
    Rep Power
    2
    With several, I'd like to know which function called them so as to tailor the output.
    Erm...why?

    Also, what requinix said.

    You're effectively saying you want to delegate returning of data to the caller, which isn't necessary. Let the caller change the data however they wish, a la:

    PHP Code:
    function thingThatDoesStuff()
    {
        return [ 
    'foo' => ];
    }

    function 
    thingThatDoesOtherStuff()
    {
        
    $data thingThatDoesStuff();

        return 
    $data['foo']*2;
    }

    // etc 

IMN logo majestic logo threadwatch logo seochat tools logo