Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the __FILE__ constant for a function's caller in PHP

Tags:

php

I know the __FILE__ magic constant in PHP will turn into the full path and filename of the currently executing file. But is there a way I can get the same information for a function's calling file? For example:

//foo.php:
include "bar.php";
call_it();

//bar.php
function call_it() {
    echo "Calling file: ".__CALLING_FILE__;
}

which would output Calling file: ....../foo.php.

I know there's no __CALLING_FILE__ magic constant, or a magic constant to handle this, but is there a way I can get that information? The least-hackish solution would be ideal (eg. using a stack trace would be pretty hacky) but in the end I just need it to work.

like image 454
Carson Myers Avatar asked Nov 26 '09 06:11

Carson Myers


2 Answers

you should take a look at the stack trace for doing such things. PHP have a function called debug_backtrace

include "bar.php";
call_it();

//bar.php
function call_it() {
   $bt =  debug_backtrace();

   echo "Calling file: ". $bt[0]['file'] . ' line  '. $bt[0]['line'];
}

hope it helps

on the same principle you could find debug_print_backtrace useful, it do the same things but php handle the formating and printing of all the information by itself.

like image 184
RageZ Avatar answered Oct 08 '22 20:10

RageZ


debug_backtrace() is your friend

That's what we use to dump the full stack trace for the current line. To adjust it to your case, ignore the top of $trace array.

class Util_Debug_ContextReader {
    private static function the_trace_entry_to_return() {
        $trace = debug_backtrace();

        for ($i = 0; $i < count($trace); ++$i) {
            if ('debug' == $trace[$i]['function']) {
                if (isset($trace[$i + 1]['class'])) {
                    return array(
                        'class' => $trace[$i + 1]['class'],
                        'line' => $trace[$i]['line'],
                    );
                }

                return array(
                    'file' => $trace[$i]['file'],
                    'line' => $trace[$i]['line'],
                );
            }
        }

        return $trace[0];
    }

    /**
     * @return string
     */
    public function current_module() {
        $trace_entry = self::the_trace_entry_to_return();

        if (isset($trace_entry['class']))
            return 'class '. $trace_entry['class'];
        else
            return 'file '. $trace_entry['file'];

        return 'unknown';
    }

    public function current_line_number() {
        $trace_entry = self::the_trace_entry_to_return();
        if (isset($trace_entry['line'])) return $trace_entry['line'];
        return 'unknown';
    }
}
like image 44
Ivan Krechetov Avatar answered Oct 08 '22 20:10

Ivan Krechetov