Can an included PHP file know where it was included from?

后端 未结 6 1727
遇见更好的自我
遇见更好的自我 2020-12-10 11:31

For example,

This is index.php


Can header.php know it was included by index.php?

相关标签:
6条回答
  • 2020-12-10 11:45

    PHP tracks the file that does the including for you in the backtrace. With a little helper function you can get the filename that had the last include command:

    /**
     * get filename that included this file
     *
     * @return string filename
     */
    function include_by() {
        $bt = debug_backtrace(0);
        while ($b = array_shift($bt)) {
            if (in_array($b['function'], array('require', 'require_once', 'include', 'include_once'), 1)) {
                return $b['file'];
            }
        }
        throw new BadFunctionCallException('Not an include.');
    }
    

    Usage:

    main.php:

    <?php
    include('sub.php');
    

    sub.php:

    <?php
    echo basename(include_by()); # main.php
    

    See as well a related usage of the backtrace: Caller function in PHP 5?.

    0 讨论(0)
  • 2020-12-10 11:49
    debug_print_backtrace();
    

    Check PHP docu

    0 讨论(0)
  • 2020-12-10 11:50

    get_included_files() provides a stack of the files included, in the order they are included, which in my case gave me everything I needed.

    Specifically, if you call get_included_files() within a file that has been included, that file's own file-path will be the most recent entry on the stack returned by get_included_files(), the one that included it is above that, etc.

    The caveat is that files are only listed once, so if the same file is included more than once, only the first include will show up in the stack. For my purposes that wasn't an issue, but it definitely means this won't work in all cases.

    Specific example: imagine the file 'test1.php' includes 'test_include.php'. The result of get_included_files() from the perspective of 'test_include.php' after loading test1.php in the browser are as follows (given, as you can see, that I've got an auto_prepend file, which in turn loads an autoloader).

    array(4) {
      [0]=>
      string(21) "/www/auto_prepend.php"
      [1]=>
      string(19) "/www/autoloader.php"
      [2]=>
      string(14) "/www/test1.php"
      [3]=>
      string(21) "/www/test_include.php"
    }
    

    So test_include.php only has to do a little array_pop'ing to figure out who included it.

    0 讨论(0)
  • 2020-12-10 11:56

    $_SERVER['PHP_SELF'] should still point to file originally accessed, or you could set a variable before the require, eg:

    $section = 'home';
    require_once('header.php');
    

    ...

    if ($section == 'home') {
        ...
    }
    
    0 讨论(0)
  • 2020-12-10 12:00

    Easiest way in the web server environment: $_SERVER['SCRIPT_FILENAME'] will show the original file that is called.

    Universal way - debug_backtrace() will show you all previous steps of the execution, which will include calls to require/include functions.

    0 讨论(0)
  • 2020-12-10 12:08

    While $_SERVER['PHP_SELF'] will contain the currently executing script, there is no way to determine from an included file which specific script caused the include.

    This means that if a.php includes b.php, which includes c.php, c.php will have no way of knowing that b.php was the includer. The best you can get is that a.php is the currently executing script.


    Edit: Yup, my above answer is technically wrong -- you can use debug_backtrace to find the caller, even without functions, up until PHP 5.4, which removes this functionality.

    a.php:

    <?php
    echo 'A';
    include 'b.php';
    

    b.php:

    <?php
    echo 'B';
    include 'c.php';
    

    c.php:

    <?php
    echo 'C';
    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
            )
    
    )
    

    So while this works, you probably shouldn't use it. debug_backtrace can be a noticeable performance drag when used excessively.

    0 讨论(0)
提交回复
热议问题