5

do you guys know how can i determine from what file was a function called inside of that function?

I was thinking of using debug_backtrace .. but that does not look as an elegant way to do it, and they also enumarate other reasons in another question here

So what other alternatives are there ?

thanks a lot

Community
  • 1
  • 1
Gabriel Solomon
  • 29,065
  • 15
  • 57
  • 79
  • Why do you need to know from where the current function has been called? As the linked question states, you should rethink your design if your functions really need to know who called them. – Gumbo Apr 13 '09 at 12:03
  • i have a view Class and want to not specify the whole path of the view ... but only the name and that to result in the view located in the same directory as the view that called the class. – Gabriel Solomon Apr 13 '09 at 15:22
  • It sounds like you're about to shoot your foot off. Don't do that. – troelskn Apr 13 '09 at 16:13

5 Answers5

3

The responses here by the mickey mouse crew are typical of the online PHP community! Instead of sharing the answer they ask you why you might need it. Never mind the fact that solomongaby asks a valid question and it's a pretty normal feature to have in standard IDE's and more professional languages like Java and Objective-C.

Solomongaby, this is the simplest way to get you what you need:

$bt = debug_backtrace();
$end = end($bt);
var_dump($end['class']); //or var_dump($end['file']);
PostCodeism
  • 1,070
  • 1
  • 12
  • 20
3

I borrowed this code some time ago from somewhere and it works like a charm using debug_backtrace(). Hope you find it useful:

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

    $output = '';
    foreach ($backtrace as $bt) {
        $args = '';
        foreach ($bt['args'] as $a) {
            if (!empty($args)) {
                $args .= ', ';
            }
            switch (gettype($a)) {
                case 'integer':
                case 'double':
                    $args .= $a;
                    break;
                case 'string':
                    //$a = htmlspecialchars(substr(, 0, 64)).((strlen($a) > 64) ? '...' : '');
                    $args .= "\"$a\"";
                    break;
                case 'array':
                    $args .= 'Array('.count($a).')';
                    break;
                case 'object':
                    $args .= 'Object('.get_class($a).')';
                    break;
                case 'resource':
                    $args .= 'Resource('.strstr($a, '#').')';
                    break;
                case 'boolean':
                    $args .= $a ? 'TRUE' : 'FALSE';
                    break;
                case 'NULL':
                    $args .= 'Null';
                    break;
                default:
                    $args .= 'Unknown';
            }
        }
        $output .= '<br />';
        $output .= '<b>file:</b> '.@$bt['file'].' - line '.@$bt['line'].'<br />';
        $output .= '<b>call:</b> '.@$bt['class'].@$bt['type'].@$bt['function'].'('.$args.')<br />';
    }
    return $output;
}
Seb
  • 24,920
  • 5
  • 67
  • 85
  • i am looking for an alternative for using debug_backtrace function. – Gabriel Solomon Apr 13 '09 at 15:22
  • 1
    Then I believe you should rephrase your question, as I understood your problem was that debug_backtrace was presenting its output ugly. Anyway, I don't think there's a simple alternative to debug_backtrace... – Seb Apr 13 '09 at 16:53
2

From within the function debug_backtrace() is the only way to determine the caller, unless of course you pass that information as parameter.

Note, that you cannot use default values to do this. E.g.:

function f($param1, $param2, $caller=__FUNCTION__) ...

__FUNCTION__ will be evaluated at parse time, so it'll always have the same value. The function in which scope f is declared.

vartec
  • 131,205
  • 36
  • 218
  • 244
1

You will not have many options there. The other option (which was posted in the other question) to force the caller to provde it's information with the function call (using PHP magic constants):

callFunction(1, 2, 3, __FUNCTION__)
callFunction(1, 2, 3, __CLASS__,  __METHOD__)
callFunction(1, 2, 3, $this,  __METHOD__)

  or

$class = new ReflectionClass( __CLASS__ ); 
$method = $class->getMethod( __METHOD__ );
callFunction(1, 2, 3, $method) // $method would be a ReflectionMethod obj

would be a possible alternative. But it's

  • obfuscating your code
  • can be "manipulated" which might cause the code of callFunction to fail and it would be quite difficult to track those errors down.

If I were in your place, I would try to avoid it in a function that is used throughout your code. use debug_backtrace (even if it might be 'slow'). Readable code wins over fast code.

Marcel Jackwerth
  • 53,948
  • 9
  • 74
  • 88
0

If this is for debugging purposes, you can throw an exception, and print the functions calls stack where you catch it.

Itay Moav -Malimovka
  • 52,579
  • 61
  • 190
  • 278