Is there a way to find out which FILE used require_once?
Asked Answered
C

5

7

Let's say I have the following situation:

File1.php:

<?php
require_once('init.php');
...
?>

File2.php:

<?php
require_once('init.php');
...
?>

init.php:

<?php
magic_function_which_tells_me_which_file_parsed_this_file();
...
?>

I know this is a long-shot, but is there a way to know from within init.php which file included init.php it in the current execution?

Cabbage answered 13/5, 2015 at 14:18 Comment(2)
Are you asking because you want different code included for different situations?Fic
I think that the phrase "legacy code" says enough :) I know that the init file is used, but I can not trace the execution before that.Cabbage
C
5

You are able to use debug_backtrace to find the caller even without functions:

test1.php

<?php
echo 'test1';
include 'test2.php';

test2.php

<?php
echo 'test2';
print_r(debug_backtrace());

Output

ABCArray
(
[0] => Array
    (
        [file] => /tmp/b.php
        [line] => 3
        [function] => include
    )

[1] => Array
    (
        [file] => /tmp/a.php
        [line] => 3
        [args] => Array
            (
                [0] => /tmp/b.php
            )

        [function] => include
    )
)

Anyways, I'd not recommend using it because it can be a noticeable performance drag when used excessively.

Chinookan answered 13/5, 2015 at 14:29 Comment(4)
I am not seeing the lack of this information in my php 5.5 -- do you have a reference on that assertion that it was removed? The documentation page also makes no mention of such information being removed.Corrincorrina
@ChrisBaker Sorry, I just read up on this again on the doc, and obviously i was misinformed - submitted my answer too fast :\Chinookan
OMG, I feel so stupid now, I intentionally disregarded debug_backtrace() because I thought that only works with functions.Cabbage
I added a little utility function to parse this info out of the backtrace data, might help :)Corrincorrina
C
3

At the top of init.php, you could use debug_backtrace() to get information about the stack. This will tell you, among other things, which file included the current file, and at what line.

This is a sample of the backtrace output. If you put this in a function, you'll have another layer of data. If you call it right in the file itself, then the top-most layer tells you what file included that one.

array (size=2)
  0 => 
    array (size=3)
      'file' => string 'fileThatIncudedMe.php' (length=63)
      'line' => int 6
      'function' => string 'require_once' (length=12)

You could wrap this up into a utility function:

function whoIncludedThisFile() {
    $bt = debug_backtrace();
    $includedMe = false;
    while (count($bt) > 0) {
        $set = array_shift($bt);
        if (
            array_key_exists('function', $set) === true &&
            in_array($set['function'], array('require', 'require_once', 'include', 'include_once'))
        ){
            $includedMe = array('file'=>$set['file'], 'line'=>$set['line']);
            break;
        }
    }
    return $includedMe;
}

print_r(whoIncludedThisFile());
// Array ( [file] => topLevelFile.php [line] => 2 )
Corrincorrina answered 13/5, 2015 at 14:31 Comment(2)
@ChrisBaker you got my vote, this will go straight into a gist :PChinookan
This is nice! If OP were to accept an answer between mine and yours, I'd favour yours.Szabo
A
3

Sure you can. With a debug_print_backtrace().

#0 require_once() called at [C:\xampp\htdocs\file2.php:3]

#1 require_once(C:\xampp\htdocs\file2.php) called at [C:\xampp\htdocs\file1.php:3]

This will tell you that init.php was included from file2.php on line 3.

Aport answered 13/5, 2015 at 14:32 Comment(0)
V
0

You may also try to use a variable to achieve this. Let's name it $parentFile:

$parentFile = basename(__FILE__);
require('some.file.here.php');

And in some.file.here.php:

if($parentFile == 'another.file.php')
    // do something;
Viewless answered 13/5, 2015 at 14:34 Comment(1)
yes, it would be a good approach in some situations, but in my case I did not know the parent file because I was working on really old code.Cabbage
C
0

I will chip in with an answer - obviously all the credit goes to the guys that already answered this before me.

What I did was to format the debug_backtrace output to the error log:

$debug = debug_backtrace(2 , 16);
error_log('-------------------------------' );
foreach ( $debug as $error ) {
     error_log( str_pad( $error['file' ], 120 ) . str_pad($error ['line'] , 8) . $error['function' ] );
}

The result will be one file per line containing (file,line,function) in a table manner.

Cabbage answered 13/5, 2015 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.